3

次のコードは NullPointerException を生成します -

public class MyClass {

    static MyClass instance= new MyClass(); // line 3
    static Boolean have_Instance = true;
    Boolean inst_Avail=have_Instance; // line 5

    Boolean isInstAvail(){
        return inst_Avail;
    }

    public static void main(String[] args) {
        System.out.println(instance.isInstAvail() ? "Instance is there.":""); // gives java.lang.NullPointerException
    }

}

line 3afterに移動すると、正常にline 5動作します。ここでの順序はどのように重要ですか? クラスのインスタンス化で毎回 iVar 値を設定するべきではありませんか?

4

5 に答える 5

3

3 行目でオブジェクトが作成されるとき、クラスはまだ初期化を完了しておらず、have_instance変数にはデフォルト値のnull. inst_Availこの値はオブジェクトのメンバー変数に割り当てられるためinstance.isInstAvail()mainメソッドで返される値は になりますnull

これを修正する簡単な方法は、行 3 と行 4 を交換することです。そのためhave_instance、オブジェクトが作成された時点ですでに値が設定されています。または、の代わりにhave_instanceasを宣言することもできます。ただし、これにより、プログラムは何も出力しません。booleanBooleanfalsenull

あるいは、自分がやろうとしていることを再考することもできます。クラスの初期化が完了する前にクラスのインスタンスを作成することは、特にクラスが「最終」ではない (つまり、サブクラスがある可能性がある) 場合には、あまり良い考えではありません。

于 2013-07-07T10:42:57.153 に答える
2

これらのフィールドの値を直接設定するか、静的初期化ブロックを使用して初期化する場合、フィールドの順序は重要です。それらは順番に実行されます。したがって、前方参照を行うことはできませんでした:

private int someInt = 10 + otherInt;
private int otherInt = 22;

フィールドはテキスト宣言の順序で初期化されるため、これは機能しません。2 つの静的初期化子がある場合、それらも順番に実行されます。

static { System.out.println("first"); }
static { System.out.println("second"); }

したがって、あなたの場合、instancehave_instanceに初期化するため、後者はまだnull(非プリミティブのデフォルト値)です。JVM は、MyClass割り当てられるオブジェクトを作成し、instanceそのフィールドを初期化します。つまり、 の値も設定さhave_instanceれます。inst_Availnull

いくつかの読み:

于 2013-07-07T10:53:38.210 に答える