0

この質問が以前に尋ねられたかどうかはわかりません。検索しましたが、重複する質問は見つかりませんでした。関連する質問を見つけた場合は、そのリンクに言及してください。

public class Exp 
{
    Exp()
    {
         System.out.println("Hello");      //3
    }
    {    System.out.println("Hello")};    //1
    {    static{System.out.print("x");}   //2
}

メッセージの印刷順序は 2、1、3 です。

これらの行 1 と 2 の重要性と、その実行命令の理由は何ですか?

4

4 に答える 4

3

行 "1" はインスタンス初期化子で、オブジェクトが最初に作成されたとき、コンストラクターが呼び出される前に実行されます。

行 "2" はstatic initializerで、オブジェクトが作成される前に、クラスが最初にロードされたときに実行されます。

JLS のセクション 12.5では、インスタンス初期化子をいつ実行するかを指定しています。

新しく作成されたオブジェクトへの参照が結果として返される直前に、指定されたコンストラクターが処理され、次の手順を使用して新しいオブジェクトが初期化されます。

コンストラクターの引数を、このコンストラクター呼び出し用に新しく作成されたパラメーター変数に割り当てます。

このコンストラクターが、(this を使用して) 同じクラス内の別のコンストラクターの明示的なコンストラクター呼び出し (§8.8.7.1) で始まる場合、引数を評価し、これらの同じ 5 つの手順を使用してそのコンストラクター呼び出しを再帰的に処理します。そのコンストラクターの呼び出しが突然完了すると、このプロシージャは同じ理由で突然完了します。それ以外の場合は、ステップ 5 に進みます。

このコンストラクターは、(this を使用して) 同じクラス内の別のコンストラクターの明示的なコンストラクター呼び出しで開始されません。このコンストラクターが Object 以外のクラス用である場合、このコンストラクターは、(super を使用して) スーパークラス コンストラクターの明示的または暗黙的な呼び出しから開始します。これらの同じ 5 つの手順を使用して、引数を評価し、そのスーパークラス コンストラクター呼び出しを再帰的に処理します。そのコンストラクターの呼び出しが突然完了すると、このプロシージャは同じ理由で突然完了します。それ以外の場合は、ステップ 4 に進みます。

このクラスのインスタンス初期化子とインスタンス変数初期化子を実行し、インスタンス変数初期化子の値を対応するインスタンス変数に割り当てます。この順序は、クラスのソース コードにテキストで表示される左から右の順序です。これらの初期化子のいずれかを実行すると例外が発生した場合、それ以上の初期化子は処理されず、このプロシージャは同じ例外で突然終了します。それ以外の場合は、ステップ 5 に進みます。

このコンストラクターの残りの本体を実行します。その実行が突然完了した場合、このプロシージャは同じ理由で突然完了します。それ以外の場合、この手順は正常に完了します。

(私のものを強調)

コンストラクターの本体の残りの部分は、インスタンス初期化子の後に実行されます。

于 2013-10-22T19:36:21.507 に答える
1

http://docs.oracle.com/javase/tutorial/java/javaOO/initial.htmlを参照してください。

静的初期化ブロックは、中かっこ { } で囲まれ、前に static キーワードが続く通常のコード ブロックです。次に例を示します。

static {
    // whatever code is needed for initialization goes here
}

クラスは任意の数の静的初期化ブロックを持つことができ、クラス本体のどこにでも表示できます。ランタイム システムは、静的初期化ブロックがソース コードに表示される順序で呼び出されることを保証します。

于 2013-10-22T19:37:23.317 に答える