JAVA/BASIC

자바(JAVA) 중첩클래스 - 로컬클래스와 익명객체의 로컬변수의 사용제한

유혁스쿨 2023. 4. 11. 18:49
728x90
반응형

로컬클래스란

메소드 내부에서 선언되는 중첩 클래스를 말한다.

메소드가 호출되어 실행되고 있을 때만 객체로 생성되어 사용할 수 있다.

메소드 내부에서만 사용되므로 접근을 제한할 필요가 없기 때문에 접근제한자(private, public) 및 static을 붙일 수 없다.

따라서 로컬클래스 내부에는 인스턴스 필드와 메소드만 선언이 가능하고 정적 필드와 메소드는 선언할 수 없다.

void method() {
    class D {
        D() {} //생성자
        int field1; //인스턴스 필드
        static int field2; //정적 필드
        void method1() {} //인스턴스 메소드
        static void method2() {} //정적 메소드
    }
    D d = new D();
    d.field1 = 3;
    d.method1();
}

위 코드와 같이 선언하면 static이 붙은 정적 필드와 메소드는 컴파일 오류가 발생한다.

다시한번 설명하자면 로컬 클래스는 메소드가 실행될 때 메소드 내에서 객체를 생성하고 사용해야 한다.

로컬 즉, 지역변수라는 의미이다. 따라서 외부에서는 선언자체가 불가능하다.

 

 

로컬클래스 사용제한

로컬클래스 내부에서 바깥 클래스의 필드나 메소드를 제한없이 사용할 수 있다.

문제는 메소드의 매개변수나 로컬 변수를 로컬 클래스에서 사용할 때이다.

로컬 클래스의 객체는 메소드 실행이 끝나도 힙 메모리 영역에 존재해서 계속 사용될 수 있다.

매개 변수나 로컬 변수는 메소드 실행이 끝나면 스택 메모리 영역에서 사라지기 때문에 로컬 객체에서 사용할 경우 문제가 발생한다.

자바는 이 문제를 해결하기 위해 컴파일 시 로컬 클래스에서 사용하는 매개 변수나 로컬 변수의 값을 로컬 클래스 내부에 복사해 두고 사용한다.

그리고 매개 변수나 로컬 변수가 수정되어 값이 변경 되면 로컬 클래스에 복사해 둔 값과 달라지는 문제를 해결하기 위해 매개 변수나 로컬 변수를 final로 선언해서 수정을 막는다.
(개발자가 실수로 중간에 수정하는 경우를 막기위해)

결론적으로 말해서 로컬 클래스에서 사용 가능한 것은 final로 선언된 매개변수와 로컬 변수뿐이라는 것이다.

자바 7 이전까지는 final 키워드 없이 선언된 매개 변수와 로컬 변수를 로컬 클래스에서 사용하면 컴파일 에러가 발생했다.

하지만 자바 8 부터는 final없이 선언된 매개변수와 로컬변수를 사용해도 컴파일 에러가 나지 않는다.

자바 8 부터는 final을 선언하지 않아도 여전히 값을 수정할 수 있는 final의 특성을 갖게된다.

final 키워드 존재 여부의 차이점은 로컬 클래스의 복사 위치이다.

final 키워드가 있다면 로컬 클래스의 메소드 내부에 지역 변수로 복사되지만, final 키워드가 없다면 로컬 클래스의 필드로 복사된다.

하지만 우리는 로컬 클래스의 내부 복사 위치에 신경 쓸 필요 없이 로컬 클래스에서 사용된 매개 변수와 로컬 변수는 모두 final 특성을 갖는다는 것만 알면 된다.

 

이것은 익명 객체 및 익명 구현 객체에도 해당한다. (클래스상속or 인터페이스구현)

만약 메소드 내부에 익명객체를 구현하였다면 로컬클래스와 동일하게 적용된다.

로컬 클래스와 익명 클래스와의 차이점은 클래스 이름의 존재 여부만 다를 뿐 동작 방식은 동일하다.

 

 

 

728x90
반응형