4

私はこのコードを実行しようとしていますが、静的で最終的なこの動作を見つけました:コードはAの静的ブロックを実行せずに実行されます.理由を教えてください.

class A {
  final static int a=9;
    static { //this block is not executing ??
      System.out.println("static block of A");
     }
}

class Manager {
  static {
    System.out.println("manager sib");
  }

  public static void main(String ...arg) {
    System.out.println("main");
    System.out.println(A.a);
  }
}

クラス A の静的ブロックが実行されないのはなぜですか?

4

3 に答える 3

7

問題は、それA.a定数変数であることです。

final であり、コンパイル時の定数式 (§15.28) で初期化されるプリミティブ型または型 String の変数は、定数変数と呼ばれます。

したがって、メソッドは次のように正確Manager.mainにコンパイルされます。

public static void main(String ...arg) {
    System.out.println("main");
    System.out.println(9);
}

への実際の参照はA.aもうないので、Aクラスは存在する必要さえありません。初期化は言うまでもありません。(削除A.classしても実行できますManager。)

型が初期化されていることを確認するために using に依存している場合はA.a、代わりに no-op メソッドを追加しないでください。

public static void ensureClassIsInitialized() {
} 

次に、メソッドからそれを呼び出しますmain。ただし、これを行う必要があるのは非常にまれです。

于 2013-03-19T20:05:57.983 に答える
1

仕様http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf セクション 4.12.1 によると、

final であり、コンパイル時の定数式 (§15.28) で初期化されるプリミティブ型または型 String の変数は、定数変数と呼ばれます。変数が定数変数であるかどうかは、クラスの初期化 (§12.4.1)、バイナリ互換性 (§13.1、§13.4.9)、および明確な代入 (§16) に関して意味を持つ場合があります。

定数にアクセスするだけなので、クラスの初期化は必要ありません。

于 2013-03-19T20:29:31.830 に答える
0

必要なクラスを強制的にロードできます。

public final class ClassUtils {
  private ClassUtils() {}

  public static void forceLoad(Class<?>... classes) {
    for (Class<?> clazz : classes) {
      try {
        Class.forName(clazz.getName(), true, clazz.getClassLoader());
      } catch (ClassNotFoundException e) {
        throw new AssertionError(clazz.getName(), e);
      }
    }
  }
}

class Manager {
  static {
    ClassUtils.forceLoad(A.class);
// ...
  }

  public static void main(String ...arg) {
// ...
  }
}
于 2015-06-09T21:11:05.487 に答える