16

重複の可能性:
Java静的クラスの初期化

文字列変数が整数ではなく初期化ブロックで更新されるのはなぜですか(ブロックが最初に書き込まれている場合でも)

class NewClass
{
    static 
    {
       System.out.println(NewClass.string+" "+NewClass.integer);
    }

    final static String string="static";
    final static Integer integer=1;

    public static void main(String [] args)//throws Exception
    {
    }
}

私の出力は

static null

PS:文字列変数の初期化は、最後の修飾子を挿入したときにのみブロックの前で発生することにも気づきました。それはなぜですか?なぜ整数でもないのですか?私もそれを最終的な静的として宣言しました

4

3 に答える 3

20

JLS のセクション 12.4.2から、適切に切り取ったもの:

C を初期化する手順は次のとおりです。

  • 次に、値がコンパイル時の定数式であるインターフェイスの最終的なクラス変数とフィールドを初期化します (§8.3.2.1、§9.3.1、§13.4.9、§15.28)。

  • 次に、クラスのクラス変数初期化子と静的初期化子、またはインターフェイスのフィールド初期化子を、単一のブロックであるかのように、テキストの順序で実行します。

したがって、コンパイル時定数以外の場合は、「すべての変数」の次に「すべての静的初期化子」の場合、またはその逆の場合ではありません。テキストの順序でそれらすべてをまとめたものです。あなたが持っていた場合:

static int x = method("x");

static {
    System.out.println("init 1");
}

static int y = method("y");

static {
    System.out.println("init 2");
}

static int method(String name) {
    System.out.println(name);
    return 0;
}

出力は次のようになります。

x
init 1
y
init 2

Makingxまたはyfinal でさえ、コンパイル時の定数ではないため、ここでは影響しません。

PS:また、文字列変数の初期化は、最終修飾子を挿入したときにのみブロックの前に発生することに気付きました。

その時点で、これはコンパイル時の定数であり、それを使用する場合は基本的にインライン化されます。さらに、上記のように、変数値は残りの初期化子の前に割り当てられます。

JLS のセクション 15.28では、コンパイル時の定数が定義されています。これには、すべてのプリミティブ値 とStringが含まれますが、 などのラッパー型は含まれませんInteger

于 2012-09-16T16:11:34.767 に答える
7

これがあなたの質問に対する短くて簡単な答えです....

static Variable:

static 変数は、がをJVM ロードするときに実行され、 がインスタンス化されるか呼び出されるときにロードされます。ClassClass static method

static Block or static Initializer Block:

static static Initializer ブロックは、インスタンス化される前、または呼び出される前、および使用される前であっても初期化されます。Classstatic methodstatic variable

///////// 編集部分 /////////

class NewClass {

    final static String string = "static";
    final static Integer integer = 1;

    static {
        System.out.println(NewClas.string + " " + NewClas.integer);
    }

    public static void main(String [] args) { // throws Exception
        new NewClas();
    }

}

上記は印刷されます static 1

その理由は、JVMがとして知られる最適化プロセスConstant foldingを実行し、定数変数の事前計算を行うためです。

さらに、あなたの場合、static null原因はConstant foldingラッパーオブジェクトではなくプリミティブ型に適用されます。あなたの場合、その整数...

于 2012-09-16T16:24:34.350 に答える
1

それらは指定された順序(フィールドと静的ブロック)で初期化されます。そのため、出力される値はnull、静的ブロックの後に定義された静的フィールドには何も割り当てられませんでした。

于 2012-09-16T16:09:51.067 に答える