まず、パズル:次のコードは何を出力しますか?
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
下のネタバレ。
Xscale(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。これは問題であり、の定義ではありません。