먼저 퍼즐 : 다음 코드는 무엇을 인쇄합니까?
public class RecursiveStatic {
public static void main(String[] args) {
System.out.println(scale(5));
}
private static final long X = scale(10);
private static long scale(long value) {
return X * value;
}
}
대답:
0
아래 스포일러.
당신이 인쇄 할 경우 X
크기 (길이) 및 재정에 X = scale(10) + 3
의 인쇄가 될 것입니다 X = 0
후 X = 3
. 이는 X
일시적으로 설정되어 0
있고 나중에 설정되어 있음을 의미합니다 3
. 이것은 위반입니다 final
!
정적 수정자는 최종 수정 자와 함께 상수를 정의하는 데에도 사용됩니다. 최종 수정자는 이 필드 의 값을 변경할 수 없음을 나타냅니다 .
출처 : https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html [강조 추가]
내 질문 : 이것은 버그입니까? 인가 final
잘못 정의?
. 여기에 내가 관심 오전 코드입니다
X
: 두 개의 서로 다른 값을 할당 0
하고 3
. 나는 이것이 위반이라고 생각합니다 final
.
public class RecursiveStatic {
public static void main(String[] args) {
System.out.println(scale(5));
}
private static final long X = scale(10) + 3;
private static long scale(long value) {
System.out.println("X = " + X);
return X * value;
}
}
이 질문은 Java 정적 최종 필드 초기화 순서 의 가능한 복제본으로 표시되었습니다 . 다른 질문은 초기화 순서를 다루고 내 질문은 태그 와 결합 된 순환 초기화를 다루기 때문에이 질문은 중복 되지 않는다고 생각합니다 final
. 다른 질문만으로도 내 질문의 코드가 오류를 발생시키지 않는 이유를 이해할 수 없습니다.
때이 에르네스토가 얻을 수있는 출력을 조사하여 특히 분명하다 a
태그입니다 final
, 그는 다음과 같은 출력을 얻을 :
a=5
a=5
내 질문의 주요 부분과 관련이없는 것은 final
무엇입니까? 변수 는 어떻게 변수를 변경합니까?
A blank final instance variable must be definitely assigned (§16.9) at the end of every constructor (§8.8) of the class in which it is declared; otherwise a compile-time error occurs.
X
멤버 를 참조하는이 방법은 수퍼 클래스 생성자가 완료되기 전에 서브 클래스 멤버를 참조하는 것과 같습니다final
. 이는의 정의가 아니라 문제입니다 .