잘못된 코드입니다.
class BB { static int a = 0 ; public BB() { a++ ; System.out.println("执行BB" + a) ; } public void printA() { System.out.println("a= " + a) ; } } public class CC { static { a = new BB() ; a.printA() ; //报错说非法的前向引用 } static BB a = new BB() ; public staic void main(String args[]) { CC c = new CC() ; } }
정적 코드 블록에서 a를 초기화했는데도 여전히 오류가 발생하는 이유는 무엇입니까?
이유는 초기화 과정에서 멤버 변수에 대한 Java의 제한 때문입니다.
멤버 변수 a가 다음 4가지 사항을 충족하면 사용하기 전에 선언해야 합니다.
C를 직접 설정합니다. 멤버 변수가 포함된 클래스 또는 인터페이스
a가 C 또는 정적 멤버/비정적 멤버 초기화 또는 C의 정적 또는 비정적 코드 블록에 나타나는 경우
a가 할당 불평등의 lvalue가 아닌 경우
간단한 이름을 통해 액세스
내가 작성한 코드에서 a.printA() 는 CC의 정적 코드 블록에 나타나며 간단한 이름을 통해 직접 액세스되며(즉, a를 직접 사용하여) 할당 불평등의 lvalue가 아닙니다. 따라서 "불법 전방 참조" 오류가 보고됩니다
이것은 Java 언어 사양의 원본 코드입니다(중국어는 내 주석입니다):
class UseBeforeDeclaration { static { x = 100; // ok - assignment , 赋值表达式的左值 int y = x + 1; // error - read before declaration , 赋值表达式的右值 int v = x = 3; // ok - x at left hand side of assignment , 左值 int z = UseBeforeDeclaration.x * 2; // ok - not accessed via simple name , 是通过类.静态变量 的形式访问, 而非直接简单访问 Object o = new Object() { void foo() { x++; } // ok - occurs in a different class , 不是CC的代码块或成员初始化中,而是在一个全新的内部类的函数中 { x++; } // ok - occurs in a different class , 在一个内部类的代码块中, 和上一个类似 }; } { j = 200; // ok - assignment j = j + 1; // error - right hand side reads before declaration , 第二个右值 int k = j = j + 1; // error - illegal forward reference to j , 第三个是右值 int n = j = 300; // ok - j at left hand side of assignment , 左值 int h = j++; // error - read before declaration , 右值, 并参与了自增运算 int l = this.j * 3; // ok - not accessed via simple name 通过this.j进行访问, 非直接简单访问 Object o = new Object() { void foo() { j++; } // ok - occurs in a different class { j = j + 1; } // ok - occurs in a different class }; } int w = x = 3; // ok - x at left hand side of assignment int p = x; // ok - instance initializers may access static fields static int u = (new Object() { int bar() { return x; } }).bar(); // ok - occurs in a different class static int x; int m = j = 4; // ok - j at left hand side of assignment int o = (new Object() { int bar() { return j; } }).bar(); // ok - occurs in a different class int j; }
불법 전방 참조의 예 :
그러면 왜 i="1234"; 같은 코드가 괜찮은 걸까요?
Java에는 이러한 상황 중 일부에 대해 "양보"가 있기 때문입니다. 그 중 하나는 "간단한 이름으로 참조되는 변수는 lvalue 위치에 나타날 수 있지만 rvalue 위치에는 나타날 수 없습니다"이므로 이전 코드는 작동하지만 System. out.println(i); rvalue 참조이므로 작동하지 않습니다.
루프 초기화 및 기타 비정상적인 초기화 동작을 방지하는 것이 목적입니다.
순환 참조란 무엇인가요? 다음 예를 살펴보세요.
privateinti=j; privateintj=i;
위에 언급된 필수 확인 사항이 없으면 다음 두 줄의 코드가 컴파일되지만 i와 j가 두 변수가 모두 초기화되지 않았기 때문에 실제 할당이 아닙니다. (Java에서는 모든 변수를 사용하기 전에 초기화해야 한다고 규정합니다.)
위 내용은 Java에서 잘못된 전방 참조 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!