5
public class Main {

    static int x = Main.y;
//  static int x = y; //Not allowed; y is not defined
    static int y = x;
    public static void main(String[] args) {
        System.out.println(x);//prints 0
    }
}

なぜ私はクラスを通してyを使用することを許可されていますが、直接使用することはできませんか?

yはいつ定義されますか?

4

5 に答える 5

10

クラス変数への前方参照を管理する正確なルールは、JLSのセクション§8.3.2.3で説明されています。

8.3.2.3初期化中のフィールドの使用に関する制限

メンバーの宣言は、メンバーがstaticクラスまたはインターフェイスCのインスタンス(それぞれ)フィールドであり、次のすべての条件が満たされる場合にのみ、使用される前にテキストで表示される必要があります。

  • 使用法は、Cのインスタンス(それぞれstatic)変数初期化子またはCのインスタンス(それぞれstatic)初期化子で発生します。
  • 使用法は、割り当ての左側にはありません。
  • 使用法は単純な名前によるものです。
  • Cは、使用法を囲む最も内側のクラスまたはインターフェースです。

上記の4つの要件のいずれかが満たされない場合、コンパイル時エラーが発生します。

これは、コンパイル時エラーがテストプログラムの結果であることを意味します。

  class Test {
      int i = j;  // compile-time error: incorrect forward reference
      int j = 1;
  }

一方、次の例はエラーなしでコンパイルされます。

  class Test {
      Test() { k = 2; }
      int j = 1;
      int i = j;
      int k;
  }

Testのコンストラクター (§8.8)が3行後に宣言されたフィールドkを参照している場合でも。

これらの制限は、コンパイル時に、循環またはその他の不正な形式の初期化をキャッチするように設計されています。したがって、両方:

class Z {
  static int i = j + 2; 
  static int j = 4;
}

と:

class Z {
  static { i = j + 2; }
  static int i, j;
  static { j = 4; }
}

コンパイル時エラーが発生します。メソッドによるアクセスはこの方法ではチェックされないため、次のようになります。

class Z {
  static int peek() { return j; }
  static int i = peek();
  static int j = 1;
}
class Test {
  public static void main(String[] args) {
      System.out.println(Z.i);
  }
}

出力を生成します:

0

iの変数初期化子は、クラスメソッドpeekを使用して、jが変数初期化子によって初期化される前に変数jの値にアクセスするため、その時点ではまだデフォルト値(§4.12.5)があります。

于 2010-09-13T09:16:17.890 に答える
2

クラスを使用することにより、コンパイラはクラスが完了するまで変数の検索を延期するため、yが検出されると思いますが、コメントのように定義しただけではまだ定義されていないため、失敗します。

于 2010-09-13T09:07:27.273 に答える
1

静的変数は、クラスのロード中に、クラスで宣言された順序で定義されます。JVMがMainクラスをロードするときに、xが定義され、次にyyそのため、初期化時に直接使用することはできません。前方参照xと呼ばれるものを作成し、現在定義されていない変数を参照します。これはコンパイラにとって違法です。

を使用するMain.yと、次のことが起こると思います。

  • ロードするMainと、x初期化が呼び出されます
  • xに等しいと定義するとMain.y、コンパイラはクラスへの参照を認識するため、クラスのxメンバーの現在の値への定義を終了します。このケースは別のクラスであるかのように扱われます。yMainMain

この場合、初期化時にxyは現時点では定義されていないことに注意してください。したがってx、値は。になり0ます。

于 2010-09-13T09:13:24.080 に答える
0

それは無意味なので、あなたはそれをすることを許されていません。考えられる唯一の解釈は、yがゼロに初期化されるというものであり、すでに2つの言い方があります。これは必要ありません。

于 2010-09-13T09:07:08.710 に答える
0

おそらく、コンパイラーは、静的変数の参照を作成時にスタック内のクラスでデフォルト値を使用して作成し、提供された値を割り当てます。

于 2010-09-13T09:22:55.747 に答える