라인
b = new Test5(){{ value = 1 ;}};
는 Test5
를 확장 익명 클래스의 인스턴스를 만듭니다. 그러나 value
은 비공개이므로 익명 클래스는 수퍼 클래스의 인스턴스 변수에 액세스 할 수 없습니다.
의 익명 하위 클래스에 표시되는 value
이라는 변수가 없으므로 컴파일러는 다음 범위에서 대체를 찾습니다. 이 경우 다음 범위는 정적 main
메서드에 속합니다. 컴파일러는 인스턴스 변수 Test5
을 검색하고 인스턴스 변수를 정적 컨텍스트에서 참조 할 수 없으므로 경고를 표시합니다.
당신은 여기에 두 가지 대안이 있습니다
어느 익명 클래스 인스턴스 변수에 액세스 할 수 있도록 : 보호 int 값을;
또는 정적 main
방법에 액세스 할 수 있도록 변수 : 전용 정적 int 값;
첫 번째 대안은 실제로하고 싶은 것입니다.
@Tom : 문제는 이 아니며입니다. 먼저 정적 범위가 검색됩니다. 이 경우 인스턴스 변수 value
이 여전히 먼저 발견되어 여전히 참조 할 수 없으므로 대체 (1)이 작동하지 않습니다.
@Ken : 귀하의 instanceMethod()
은 원하지 않는 것입니다! 다음 코드를 살펴보십시오.
class Test5A {
private int value;
public void instanceMethod() {
Test5A a = new Test5A() {{ value = 1; }}; // (A)
System.out.println(this.value);
System.out.println(a.value);
}
public static void main(String[] args) {
new Test5A().instanceMethod();
}
}
이 예제 코드는 클래스의 동작을 모방 한 것입니다. 컴파일하고 실행하면 출력이 "1 0"임을 알 수 있습니다.
(A)의 익명 하위 클래스의 인스턴스 초기화 프로그램이 인스턴스 변수 인 value
에 할당하는 것처럼 보이지만 실제로는 해당 변수는 익명 클래스의 수퍼 클래스에서만 볼 수 있습니다. 대신 라인 (A)에서 value
이라는 유일한 표시 변수는 instanceMethod()
이 호출되는 Test5A
인스턴스의 인스턴스 변수입니다.따라서 하나로 변경됩니다.
이제 value
의 가시성을 증가하자
class Test5B {
protected int value;
public void instanceMethod() {
Test5B a = new Test5B() {{ value = 1; }};
System.out.println(this.value);
System.out.println(a.value);
}
public static void main(String[] args) {
new Test5B().instanceMethod();
}
}
출력이이 시간을 "0 1". 인스턴스 변수 value
은 익명 하위 클래스에 의해 상속 된이고 은 해당 인스턴스 이니셜 라이저에 표시되는입니다. 따라서 올바른 인스턴스 변수에 할당됩니다.
아니요, 실제로 액세스 할 수 있습니다. javac는 액세스 변경자가 아닌 정적 컨텍스트 인 것으로 오류를보고합니다. –
Tom이 맞습니다! 값을 액세스 할 수 있습니다 .. 그리고 언급 한 바와 같이 정적 문제는 오류로보고되고! – Ajay
"private"대신 "protected"값을 지정하면 Ajay의 예는 경고를 전혀 표시하지 않습니다. 즉 문제는 익명의 클래스가 변수를 볼 수 없으며 컴파일러는 정적이 아닌 변수가 main의 컨텍스트에서 액세스되어야한다고 생각한다는 것입니다. – janko