HihoBookStudy / EffectiveJava

이펙티브 자바 북스터디입니다.
1 stars 0 forks source link

[item 24] 익명 클래스 제약조건 #32

Closed ForteEscape closed 1 month ago

ForteEscape commented 2 months ago

Q. 책 p.148 에서 다음과 같이 서술되어 있습니다.

익명 클래스는 코드의 어디서든 만들 수 있으며 비 정적 문맥(non-static)에서 사용될 때만 외부 클래스의 인스턴스를 참조할 수 있다. 정적 문맥(static)에서라도 상수 변수 이외의 정적 멤버는 가질 수 없다.

zpqmdh commented 2 months ago

익명 클래스는 정적 문맥에서든 비정적 문맥에서든 사용할 수 있습니다. 그러나 익명 클래스는 정적 멤버를 가질 수 없습니다.

먼저 정적 멤버란 클래스 수준의 멤버이며, 선언된 클래스의 인스턴스 없이도 접근할 수 있습니다. 하지만, 익명 클래스는 내부 클래스(inner class)이기 때문에 외부 클래스의 인스턴스를 기반으로 생성됩니다. 그렇기 때문에 외부 클래스의 인스턴스에 대한 참조를 가지고 있습니다.

익명 클래스에서 정적 멤버를 선언하더라도 해당 클래스(익명 클래스)의 인스턴스가 없어서 이를 참조할 수 없습니다. 따라서, 익명 클래스에서 정적 변수를 선언하는 것이 무의미하다고 볼 수 있을 것 같습니다.

아래는 익명 클래스의 사용 예제입니다.

public class AnonymousClassExample {

    public static void main(String[] args) {
        // final로 선언된 int 변수
        final int count = 5;

        // 익명 클래스를 사용하여 Runnable 객체 생성
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                // final 변수인 count를 익명 클래스 내부에서 사용
                for (int i = 0; i < count; i++) {
                    System.out.println("Count: " + i);
                }
            }
        };

        // 익명 클래스로 생성한 Runnable 객체를 이용하여 쓰레드 생성
        Thread thread = new Thread(runnable);

        // 쓰레드 시작
        thread.start();
    }
}

outer class에서 선언된 final 필드를 사용하는 걸 확인할 수 있는데, 이는 상수로 사용하고 있기 때문입니다.

정리하자면 익명 클래스 내부에서는 이미 외부 범위에서 정의된 final 변수나 outer 클래스의 인스턴스 변수(non-static)를 사용할 수 있지만, 새로운 변수를 정의할 수는 없습니다. 이는 익명 클래스가 클래스 선언 없이 사용되는 일회성의 객체이기 때문에, 클래스 내에 새로운 멤버를 선언할 수 없기 때문입니다!