0

コードをコンパイルするときに問題が発生しています。コードをコンパイルすると、クラス foo で foo2.var が null を返しますが、その理由がわかりません。foo2 クラスで foo2.var を null にするために foo2 クラスで静的初期化を行う方法に何か問題がありますか?

どんな助けでも大歓迎です。

public class foo extends bar {
  public final static String blah = foo2.var;
  ...
}

public abstract class bar {
  ...
}

public class foo2 extends bar {
  public final static String var;

  static {
    var = "newstring";
  }
  ...
}

この例では、foo2.var 行にヌル ポインター エラーがあります。

4

5 に答える 5

3

vartryのタイプが指定されていませんpublic final static String VAR;

そして、なぜそれだけではないのですか

public class foo2 extends bar {
  public final static String var = "newstring";
于 2013-11-20T17:47:05.277 に答える
2

静的フィールド (値がコンパイル時定数式ではない) にアクセスすると、そのフィールドを宣言するクラスの初期化がトリガーされ、その間に静的初期化子が実行されます。ただし、初期化子間に循環依存関係がない場合、初期化はフィールドが読み取られるまでに完了したことが保証されるだけです。

たとえば、プログラムを実行すると

class Bar {
    static final long bar;

    static {
        System.out.println("Assigning bar");
        bar = Foo.foo;
    }
}
class Foo extends Bar {
    static final long foo;

    static {
        System.out.println("Assigning foo");
        foo = 1;
    }
}

public class Test {
    public static void main(String[] args) {
        new Foo();
        System.out.println(Bar.bar);
    }
}

次の出力が得られます。

Assigning bar
Assigning foo
0
1

の新しいインスタンスを作成するためFooFoo.classが初期化され、最初Bar.classに のフィールドを読み取るスーパークラス が初期化されますFoo.classが、Foo.class既に初期化されています。Java 言語仕様では、セクション 12.4.2 のステップ 3で、このような再帰的な初期化がすぐに完了することを義務付けています。つまり、呼び出し元には、部分的に初期化された状態のクラスが表示されます。つまり、Foo.fooは読み取られた時点で割り当てられていないため、デフォルト値の 0 が含まれています。その値が に割り当てられBar.bar、 の初期化が完了しますBar.class。次に、イニシャライザをFoo.class実行して の初期化を再開し、イニシャライザFoo.fooを 1 に設定します。

実際には、クラスの依存関係を確認し、イニシャライザ間に循環的な依存関係がないようにプログラムを構成することをお勧めします。

于 2013-11-20T18:28:20.467 に答える
0

var 型を指定します。

また、コーディング規約により、クラス名は CamelCase と定数、UNDERSCORED_CAPS で記述する必要があります。

public class Foo2 {
   public final static VAR = "newstring"; // why not?
...
}

また、いくつかの変数で foo2 クラスをシャドウすることもできます。インポートを確認します。クラスの静的フィールド参照は NPE を生成できないためです。

于 2013-11-20T17:49:51.410 に答える