まず、パズル:次のコードは何を出力しますか?
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
scale(long)で印刷してを再定義するX = scale(10) + 3
と、印刷はにX = 0
なりX = 3
ます。つまり、X
は一時的にに設定され0
、後でに設定され3
ます。これは違反ですfinal
!
static修飾子は、final修飾子と組み合わせて、定数の定義にも使用されます。最後の修飾子は、このフィールドの値を変更できないことを示しています。
ソース:https : //docs.oracle.com/javase/tutorial/java/javaOO/classvars.html [強調を追加]
私の質問:これはバグですか?されfinal
不明確な?
これが私が興味を持っているコードです
X
。2つの異なる値が割り当てられています: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 static finalフィールドの初期化順序の重複の可能性があるというフラグが付けられています。他の質問は初期化の順序を扱っているので、この質問は重複していないと思いますが、私の質問は、final
タグ。他の質問だけでは、なぜ私の質問のコードがエラーにならないのか理解できません。
これは、ernestoが取得する出力を見ると特に明確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
。これは問題であり、の定義ではありません。