2016-08-05 7 views
-2

私はJavaの本質について混乱しています。開始時の静的参照変数とインスタンス参照変数の違いは何ですか?

public class InitItself1 { 

    public InitItself1(){} 

    private InitItself1 me = new InitItself1(); 
} 

もちろん、上記のクラスのインスタンスを作成するときにStackOverFlowErrorが発生することはわかっています。上記のクラスは、変数 "me"の開始のために再帰的に開始されます。

しかし、当然のことながら

public class InitItself2 { 

    public InitItself2(){} 

    private static InitItself2 me = new InitItself2(); 
} 

上記のクラスの結果、 "InitItself2は" "InitItself1"、前クラスに異なっています。これは正常に動作し、エラーは発生しませんでした。私が知っているように、静的変数とブロックがロードされているクラスでは、静的変数の開始と静的ブロックの実行が実行されます。

私が混乱させているのは、両方のクラスの変数「InitItself1」と「InitItself2」が開始されている変数と同じであると思います。両方のクラスを開始する際に「再帰的に開始する」ことが起こると考えられます。

私の欠点は何ですか? よろしくお願いします。 ありがとう:)

+4

を与えるあなたは、静的変数が唯一の代わりにインスタンスごとの、クラスごとに一度初期化されているという事実について混乱はありますか? – Kayaman

+0

カヤマン、そうではありません。私は、開始静的変数がどのように実行されるのか混乱しています。 – ParkCheolu

+3

通常の方法で、クラスがロードされるとき。 – Kayaman

答えて

2

2番目のケースではStackOverFlowErrorを取得しません。あなたが言ったように、クラスがロードされると静的変数が開始されます。クラスは一度だけロードされるため、スタティックInitItself2 meは一度しかインスタンス化されません。コンストラクタを使用して新しいオブジェクトを作成しても、クラスを再読み込みする必要はありません。

public final class InitItself { 

    static { 
     System.out.println("Class is loaded"); 
    } 

    private static InitItself me = new InitItself(); 

    static { 
     System.out.println("me is instantiated"); 
    } 

    public InitItself() { 
     System.out.println("Constructor called, me=" + me); 
    } 

    public static void main(String[] args) { 
     System.out.println("START"); 
     InitItself i = new InitItself(); 
     System.out.println("FINISH"); 
    } 
} 

は、次のように出力

Class is loaded 
Constructor called, me=null 
me is instantiated 
START 
Constructor called, [email protected] 
FINISH 
+0

注:クラスを初期化している間にインスタンスを作成した場合、初期化される前にstatic final変数を読み取ることができます(初期化がまだ完了していない場合)+1 –

+0

それぞれの場合に異なる結果が得られるので、コンストラクタで 'me'を表示します。 –

+0

@PeterLawreyはい、良い提案;)私は例に追加します。 – noscreenname

関連する問題