2012-04-05 1 views
12

以下のコードは正当な正参照の場合ですか?もしそうなら、なぜですか?Java Legal Forward Referencing

public class MyClass 
{ 
    private static int x = getValue(); 
    private static int y = 5; 
    private static int getValue() 
    { 
    return y; 
    } 
    public static void main(String[] args) 
    { 
    System.out.println(x); 
    } 
} 

答えて

19

上記のコードは完全に合法的なJavaです。 Javaでは、静的フィールドは次のように初期化されます。まず、すべてのフィールドが型(0、false、またはnull)の既定値に設定され、宣言された順序で初期化されます。それは、int秒のデフォルト値なので、ゼロに

  1. 設定xy:これは上記のコードは、次の操作を実行することが保証されていることを意味します。
  2. xgetValue()と呼んで初期化します。値はyです。 yがまだ初期化されていないので、それはまだ値0
  3. 初期yを持っているこれはxが値0とyを取ることを意味します。5.

に値5を取るこの動作がありますポータブルで保証されています。 You can see this here

希望すると便利です。

+0

スタティック変数とメソッドではない場合はどうなりますか? – Vibhor

+2

私はその動作が同じであると信じています - 初期化はまずすべてをデフォルト値に設定し、次にそれぞれを指定された値で初期化してからコンストラクタを呼び出します。 – templatetypedef

+1

これは、btwがコンストラクタから非最終(またはプライベート)メソッドを決して呼び出さない理由の1つです。初期化されていない最終的なフィールドを見ていても、誰かがそのメソッドをオーバーライドし、まだ作成されていない「this」を参照するのは簡単です。 – yshavit

5

コンパイルできるかどうかは正当かどうかを判断できます。他の言語とは異なり、Javaには「未定義の動作」という概念はありません。ここで起こることは完全に綴られています。直観に反するかもしれませんが、具体的には合法です。静的変数を初期化する前に呼び出されたメソッドから静的変数にアクセスすることができます。 xの初期から直接yにアクセスする表面的に類似場合 - 即ち、

private static int x = y; 
private static int y = 5; 

は、特に禁止されています。なぜ本当に強い理由はありません - それはまさにその方法です。

+0

変数が静的でない場合はどうなりますか?その場合も同じですか? – Vibhor

+0

はい、事実上同じです。静的にリストされたルールは、クラスの実際の「コンストラクタ」が存在しないため、非常にわずかに異なりますが、オブジェクトは基本的に同じ方法で初期化されます。インスタンス変数、イニシャライザ、インスタンスブロックは、外観の順に各コンストラクタに付加されます。静的な場合、イニシャライザとスタティックブロックは、順番に '()'という単一のメソッドにコンパイルされます。 –

+0

コンパイラでテストできるプログラムを持つことは、私が恐れているこのような質問には贅沢です。これはOCJP試験の模擬試験から取られます。私は今それを学んでいます。そして、試験の意図を嘲笑するのは全く無意味なこれらのばかげた質問です。 –