34

私はこのような静的ブロックを使用しようとしています:

という基本クラスがありますBase.java

public class Base {

    static public int myVar;

}

そして派生クラスDerived.java

public class Derived extends Base {

    static
    {
        Base.myVar = 10;
    }
}

私のmain機能は次のようなものです:

public static void main(String[] args)  {
    System.out.println(Derived.myVar);
    System.out.println(Base.myVar);
}

これにより、0 0期待どおりに出力が出力され10 0ます。誰かがこの動作を説明できますか? また、派生クラスに静的変数の値を設定させたい場合、どうすればそれを達成できますか?

4

5 に答える 5

24

私が理解しているように。Derivedプロパティを呼び出しません(ではなく にmyVar属します)。そしてJavaはから静的ブロックを実行していません。静的フィールドを追加してそれにアクセスすると、Java はすべての静的ブロックを実行します。BaseDerivedDerivedDerived

class Base {

    static public int myVar;

}


class Derived extends Base {

    static public int myVar2;

    static
    {
        Base.myVar = 10;
    }
}


public class Main {
    public static void main( String[] args ) throws Exception {
        System.out.println(Derived.myVar2);
        System.out.println(Base.myVar);
    }
}

Java仕様から、クラスが初期化されたとき(および静的ブロックが実行されたとき):

12.4.1 初期化が発生する場合 クラスまたはインタフェース型 T は、次のいずれかが最初に発生する直前に初期化されます。

• T はクラスであり、T のインスタンスが作成されます。
• T はクラスであり、T によって宣言された静的メソッドが呼び出されます。
• T によって宣言された static フィールドが割り当てられます。
• T によって宣言された static フィールドが使用され、そのフィールドは定数変数ではありません (§4.12.4)。
• T は最上位クラス (§7.6) であり、T (§8.1.3) 内に語彙的にネストされた assert ステートメント (§14.10) が実行されます。

于 2012-05-22T08:57:48.923 に答える
6

静的初期化ブロックは、クラスが初期化されるまで実行されません。Java 言語仕様の段落 8.7 (静的初期化子) および 12.4.1 (初期化の発生時) を参照してください。

クラスで宣言された静的初期化子は、クラスが初期化されるときに実行されます (§12.4.2)。クラス変数のフィールド初期化子 (§8.3.2) と共に、静的初期化子を使用してクラスのクラス変数を初期化できます。

以下は、JLS 12.4.1 から直接取り出した同様の例です。

class Super {
  static int taxi = 1729;
}
class Sub extends Super {
  static { System.out.print("Sub "); }
}
class Test {
  public static void main(String[] args) {
    System.out.println(Sub.taxi);
  }
}

このプログラムは以下のみを印刷します。

1729

クラス Sub は初期化されないためです。Sub.taxi への参照は、クラス Super で実際に宣言されたフィールドへの参照であり、クラス Sub の初期化をトリガーしません。

于 2012-05-22T08:52:58.737 に答える
1

の単一のコピーがmyVarあり、親クラスと子クラスの両方が同じものを共有します。子クラスが初期化されるまで。

于 2012-05-22T08:51:06.490 に答える
1

私たちがするとき

class Base {

    public static int myVar = 0;
    static {
        System.out.println("Base");
    }
}

class Derived extends Base {

    static {
        System.out.println("Derived");
        Base.myVar = 9;

    }
}

public class StaticBlock {

    public static void main(String[] args) {

        System.out.println(Base.myVar);
        System.out.println(Derived.myVar);
    }
}

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

つまり、派生クラスの静的ブロックが実行されていません..!!

于 2012-08-07T07:56:42.707 に答える
0

Java 仕様へのリンクは次のとおりです。セクション 8.7 では、静的初期化子について説明しています。それらがどのように機能するか、および呼び出される順序についての詳細を提供します。http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.7

于 2012-05-22T08:54:25.787 に答える