1. 지역클래스
- 지역 클래스(Local Class) 는 메서드 내부에 정의되는 클래스이며, 내부 클래스(Inner Class) 의 한 종류이다.
- 메서드 내에서만 사용되고, 해당 메서드가 실행되는 동안에만 유효하다.
- 선언 위치가 지역 변수처럼 코드 블럭 내부라는 점이 핵심이다.
public void process() {
int localVar = 1;
class LocalPrinter {
void print() {
System.out.println(localVar);
}
}
LocalPrinter printer = new LocalPrinter();
printer.print();
}
특징
| 특징 | 설명 |
| 코드 블럭 안에 선언 | 메서드나 생성자, 코드 블럭 내에서 정의됨 |
| 바깥 클래스의 인스턴스 멤버 접근 가능 | 바깥 클래스의 필드, 메서드에도 접근할 수 있음 |
| 지역 변수 및 매개변수 접근 가능 | localVar, paramVar 등 접근 가능 (단, 제약 있음 → 아래 설명 참고) |
| 접근 제어자 사용 불가 | 지역 변수처럼 public, private, protected 사용 불가 |
2. 지역 변수 캡처(Capture)
- 지역 클래스 내부에서는 외부 지역 변수(local variable) 에 접근 가능하지만, 그 값은 절대 변경될 수 없다.
- Java는 지역 변수의 생명 주기와 인스턴스 생명 주기의 차이 때문에, 지역 변수를 내부적으로 "복사" 하여 클래스에 넣는다.
** 즉, 값을 캡처해서 보관한다는 뜻이다.
따라서 값이 변경되면 동기화 문제가 생기므로 변경을 금지하는 것이다.
package nested.nested.local;
public class LocalOuterV3 {
private int outInstanceVar = 3;
public Printer process(int paramVar) {
int localVar = 1; // 지역변수는 스택 프레임이 종료되는순간 함께 제거
class LocalPrinter implements Printer {
int value = 0;
@Override
public void print() {
System.out.println("value = " + value);
// 지역변수에 접근가능
// 인스턴스는 지역변수보다 더 오래 살아남음
System.out.println("localVar = " + localVar);
// 매개변수에도 접근 가능
System.out.println("paramVar = " + paramVar);
// 외부클래스에도 접근가능
System.out.println("outInstanceVar = " + outInstanceVar);
}
}
LocalPrinter localPrinter = new LocalPrinter();
return localPrinter;
}
public static void main(String[] args) {
LocalOuterV3 localOuterV1 = new LocalOuterV3();
Printer printer = localOuterV1.process(2);
//printer.print()를 나중에 실행한다. process의 스택프레임이 사라진 이후에 실행
printer.print();
}
}
| 종류 | 저장 위치 | 생명 주기 |
| 클래스 변수 (static) | 메서드 영역 | 클래스 로딩 ~ 종료 |
| 인스턴스 변수 | 힙 영역 | 객체 소멸 전까지 |
| 지역 변수 | 스택 프레임 | 메서드 실행 중에만 존재 |
- 지역 변수는 메서드가 끝나면 스택 프레임과 함께 소멸되므로, 그 변수에 직접 접근하면 런타임 에러 위험
- 그래서 JVM은 접근하는 지역 변수의 복사본을 지역 클래스 내부에 넣어둠 → 이것이 캡처(Capture)
예제 코드)
정상적인 지역 변수 캡쳐
public class Example {
public Runnable createPrinter(int num) {
int localVal = 100;
class LocalPrinter implements Runnable {
public void run() {
System.out.println("num: " + num);
System.out.println("localVal: " + localVal);
}
}
return new LocalPrinter();
}
}
컴파일 에러 발생
public Runnable createPrinter(int num) {
int localVal = 100;
localVal = 200; // ❌ 캡처 변수 변경 → 컴파일 에러 발생
class LocalPrinter implements Runnable {
public void run() {
System.out.println(localVal);
}
}
return new LocalPrinter();
}
지역클래스의 사용
- 메서드 내부에서만 사용할 작고 일회성인 클래스가 필요할 때
- 특정 메서드에서만 의미가 있고, 외부에 노출할 필요가 없는 경우
- 복잡한 로직을 정리해서 메서드 내에서 분리된 실행 단위를 만들고 싶을 때
사용하면 안되는 경우
- 여러 메서드에서 공유되어야 하는 경우 → 멤버 내부 클래스 또는 일반 클래스로 구현
- 너무 많은 로직이 들어가서 가독성이 떨어질 때
- 클래스 재사용이 필요할 때
출처: 인프런 자바 중급1 - 김영한
'Java' 카테고리의 다른 글
| Java 중급 1 - 예외처리(1) (0) | 2025.05.02 |
|---|---|
| Java 중급 1 - 중첩클래스, 내부 클래스(4) (0) | 2025.04.21 |
| Java 중급 1 - 중첩클래스, 내부 클래스(2) (0) | 2025.04.13 |
| Java 중급 1 - 중첩클래스, 내부 클래스(1) (0) | 2025.04.12 |
| Java 중급 1 - 날짜와 시간(3) (0) | 2025.03.23 |