본문 바로가기
Java

Java 중급 1 - 중첩클래스, 내부 클래스(3)

by KongJiHoon 2025. 4. 16.

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 - 김영한