[Java] 중첩 클래스, 내부 클래스 2

20. 중첩 클래스, 내부 클래스 2

지역 클래스

  • 지역 클래스
    • 내부 클래스 중 하나
    • 코드 블럭 안에서 클래스를 선언한다.
    • 바깥 클래스의 인스턴스 멤버와 지역 변수에 접근 할 수 있다.
    • 인터페이스를 구현하거나, 부모 클래스를 상속할 수 있다.

변수의 생명 주기

  • 클래스 변수 (static 변수)
    • 메서드 영역에 존재한다.
    • 자바가 클래스 정보를 읽어들이는 순간부터 프로그램 종료까지 존재한다.
  • 인스턴스 변수
    • 힙 영역에 존재한다.
    • 소속된 인스턴스가 GC 되기 전까지 존재한다.
  • 지역 변수
    • 스택 영역의 스택 프레임 안에 존재한다.
    • 메서드 호출 시 생성되고, 호출 종료 시 스택 프레임이 제거되면서 지역 변수도 모두 제거된다.
    • 생존 주기가 짧다.
    • 매개 변수도 지역 변수의 한 종류이다.

지역 클래스 인스턴스의 생존 범위

  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);
            }
        }

        Printer printer = new LocalPrinter();
        //printer.print()를 여기서 실행하지 않고 Printer 인스턴스만 반환한다.
        return printer;
    }

    public static void main(String[] args) {
        LocalOuterV3 localOuter = new LocalOuterV3();
        Printer printer = localOuter.process(2);
        printer.print();
    }
  }
image
  • 지역 변수인 paramVar, localVar은 process() 메서드가 실행되는 동안에만 생존할 수 있다.
    • 메서드 종료 시, process()의 스택프레임이 제거되면서 두 지역변수도 함께 제거된다.
    • 이 때, LocalPrinter 인스턴스는 생존한다.
  • 하지만, 지역 변수의 값들이 모두 정상적으로 출력된다.

지역 클래스 - 지역 변수 캡처

  • 지역 변수 캡처(Capture) : 지역 클래스의 인스턴스를 생성하는 시점에 필요한 지역 변수를 복사해서 생성한 인스턴스 안에 함께 넣어둔다.
    1. 지역 클래스의 인스턴스 생성 시 지역 클래스가 접근하는 지역 변수를 확인한다.
    2. 지역 클래스가 사용하는 지역 변수를 복사한다. (매개 변수 포함)
    3. 복사한 지역 변수를 인스턴스에 포함한다.
    4. 복사한 지역 변수를 포함한 인스턴스가 생성된다. 인스턴스를 통해 복사한 지역 변수에 접근할 수 있다.
  • 복사한 지역 변수의 생명주기는 인스턴스의 생명주기와 같다.

지역 변수 - 사실상 final

  • final 키워드를 사용하지 않지만, 값을 변경하지 않는 지역변수를 뜻한다.
  • 만약 지역 변수의 값을 변경하게 되면 ?
    • 스택 영역에 존재하는 지역 변수의 값과 인스턴스에 캡쳐한 캡처 변수의 값이 달라지는 문제가 발생한다. (동기화 문제)
  • 자바는 캡처한 지역 변수의 값을 변하지 못하게 막아서 근본적으로 문제들을 차단한다.

익명 클래스

  • 클래스의 이름이 없는 지역클래스 종류의 하나
  • 클래스의 선언과 생성을 한 번에 처리할 수 있다.
    • 지역 클래스의 선언과 생성
      //선언
      class LocalPrinter implements Printer {
        //body
      }
          
      //생성
      Printer printer = new LocalPrinter();
      


    • 익명 클래스 - 지역 클래스의 선언과 생성을 한 번에
      Printer printer = new Printer(){
        //body
      }
      
      • Printer라는 이름의 인터페이스를 구현한 익명 클래스를 생성
      • body 부분에 Printer 인터페이스를 구현한 코드를 작성한다.
  • 익명클래스는 부모 클래스를 상속 받거나, 인터페이스를 구현해야한다.
  • 이름이 없으며, 생성자를 가질 수 없다. (기본 생성자만 사용된다.)
  • 자바 내부에서 바깥 클래스 이름 + $ + 숫자로 정의된다. (ex AnonymousOuter$1)
  • 익명 클래스의 장점
    • 클래스의 별도 정의가 필요없고, 추상클래스를 즉석에서 구현할 수 있어서 코드가 간결해진다.
  • 익명 클래스는 단 한 번만 인스턴스를 생성할 수 있다.
    • 인스턴스를 여러 번 생성하고자 하면 지역 클래스를 선언하여 사용하면 된다.




김영한의 실전 자바 중급 1편을 참고하였습니다

© 2021. All rights reserved.

yaejinkong의 블로그