1

2つの異なるファイルに2つのクラスがあり、それぞれに静的変数があります。どちらが最初に初期化されるかを予測する方法があるかどうかを知りたいです(実装に依存しますか)。私のコードはこのように見えますか?

File1:
public class A
{
  public static boolean a = Logger.log();
}

File2:
public class B
{
  public static boolean b = Logger.log();
}

File3:
public class Logger
{
  public static boolean log();
}
4

3 に答える 3

9

各クラスが最初に使用される時期によって異なります。

Java言語仕様のセクション12.4.1から:

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

  • Tはクラスであり、Tのインスタンスが作成されます。

  • Tはクラスであり、Tによって宣言された静的メソッドが呼び出されます。

  • Tによって宣言された静的フィールドが割り当てられます。

  • Tによって宣言された静的フィールドが使用され、フィールドは定数変数ではありません(§4.12.4)。

  • Tはトップレベルクラス(§7.6)であり、T(§8.1.3)内に字句的にネストされたassertステートメント(§14.10)が実行されます。

静的フィールド(§8.3.1.1)への参照は、サブクラス、サブインターフェイス、またはインターフェイスを実装するクラスの名前で参照される場合でも、実際にそれを宣言するクラスまたはインターフェイスのみの初期化を引き起こします。

JLSのセクション12.4.2は、初期化手順を詳細に指定しています。

正直なところ、明らかな依存関係がないにもかかわらず、コードで一方を他方の前に初期化する必要がある場合は、とにかく問題が発生します。

于 2013-02-18T12:34:53.690 に答える
0

JVMは、すべてのクラスの記録を保持するわけではありませんが、クラスまたはクラスの静的メンバーが要求されると、メモリからクラスをロードします。したがって、従う実際の手順は次のようになります。

クラスが初めてリクエストされたとき:

  1. すべての静的変数

  2. 静的ブロック(順序で、最初に1つ、次に2番目など)

  3. インスタンス変数(メンバー)

  4. イニシャライザーブロック(注文による)

  5. コンストラクタ

そして2回目以降:

  1. すべてのインスタンス変数(メンバー)

  2. イニシャライザーブロック(注文による)

  3. コンストラクタ。

これがお役に立てば幸いです。

ありがとう...

Mr.777

于 2013-02-18T12:33:56.833 に答える
0

あなたの例によると、Aaの前にBbを初期化する方法はありません。これは、Bクラスにアクセスすると、最初にその夕食クラスの静的初期化が呼び出されるためです。

本当にBの前にAロジックを実行する必要がある場合は、静的メソッドでカプセル化してみてください。

public class A
{
  public static boolean a;
  public static init() {
   a = log();
  }
}

public class B
{
  public static boolean b;
  public static init() {
   b = log();
  }
}

public class Main
{
  public static void main(String[] args) {
   B.init();       
   A.init();      
  }
}
于 2013-02-18T12:43:12.167 に答える