私はこのような静的ブロックを使おうとしています:
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
です。誰かがこの振る舞いを説明できますか?また、派生クラスで静的変数の値を設定したい場合、どうすればそれを実現できますか?
私が理解しているように。 Derived
プロパティは呼び出さない(myVar
はBase
に属し、Derived
には属さない)。また、JavaはDerived
から静的ブロックを実行していません。静的フィールドをDerived
に追加してアクセスすると、Javaはすべての静的ブロックを実行します。
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によって宣言された静的フィールドが割り当てられます。
•Tによって宣言された静的フィールドが使用され、フィールドは定数変数ではありません(§4.12.4)。
•Tはトップレベルクラス(§7.6)であり、T(§8.1.3)内に字句的にネストされたassertステートメント(§14.10)が実行されます。
静的初期化子-クラスが初期化されるまで、ブロックは実行されません。 Java言語仕様 段落8.7(静的初期化子)および12.4.1(初期化が発生した場合)を参照してください。
クラスで宣言された静的初期化子は、クラスが初期化されるときに実行されます(§12.4.2)。クラス変数のフィールド初期化子(§8.3.2)と一緒に、静的初期化子を使用してクラスのクラス変数を初期化できます。
JLS12.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の初期化をトリガーしません。
myVar
のコピーが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
になります
これは、派生クラスの静的ブロックが実行されていないことを意味します。
Java仕様-セクション8.7では、静的初期化子について説明しています。静的初期化子の機能と呼び出し順序について詳しく説明しています。 http:/ /docs.Oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.7