3

私のコードは次のようなものです:

public class Foo {
    public int a;
    Bar[] bar = new Bar[10];

    a = bar[0].baz;
}

public class Bar {
    public int b;

    public Bar () { //I tried doing away with this constructor, but that didn't
                    //fix anything
        b = 0;
    }

    public int Baz () {
        //do somthing
    }
}

そして、次のようなエラーメッセージが表示されます。

Exception in thread "Foo" java.lang.NullPointerException

Fooのどの行でも、クラスBarの関数または値を呼び出そうとします。bar []がnullになるのを防ぐにはどうすればよいですか?

編集:少しいじった後、私はついにそれを修正しました、みんなに感謝します!ただし、コンストラクターを呼び出して修正することはできませんでした。別の関数を作成し、その関数をMainから呼び出す必要がありました(私の場合、クラスFooは実際にはクラスMainですが、それが本当に重要な場合)。私の最終結果:

public class Foo {
    public int a;
    Bar[] bar = new Bar[10];

    public Foo () { //this constructor wasn't called for some reason... I checked this
                    //by using System.out.println... no message was print onscreen
        for (int a = 0; a < bar.length; a++)
            bar[a] = new Bar();
    }

    public static void initializeFoo () {
        for (int a = 0; a < bar.length; a++)
            bar[a] = new Bar();
    }

    public static void Foo () {
        initializeFoo();
        a = bar[0].baz;
    }
}

誰かがそれで私を助けたいですか、それとも私は別の質問を作成することになっていますか?:)

4

8 に答える 8

8
Bar[] bar = new Bar[10];

a = bar[0].baz;

上記はタイプBarの配列を作成しますが、実際のBarオブジェクトは入力しません。参照型の配列は、null参照で初期化されます。これを行う必要があります:

for(int i=0; i<bar.length; i++) {
    bar[i] = new Bar();
}
于 2010-01-24T16:12:21.530 に答える
6

これを書き込むことで参照にメモリをBar[] bar = new Bar[10];割り当てましたが、配列要素にメモリを割り当てるのは誰ですか?参照型の実際の配列は、null参照で初期化されます。

配列要素にもメモリを割り当てる必要があります。

for(int i=0; i<bar.length; ++i)
   bar[i]=new Bar();
于 2010-01-24T16:13:42.070 に答える
3

NullPointerExceptionが発生する理由は、次の行が原因です。

a = bar[0].baz;

bar[0]まだ存在していません。

何が起こっているのかというと、aFooが初期化されると、デフォルトの初期化子が実行されます(上記の行のように)。bar参照の配列として作成しBarますが、配列内の個々の場所を初期化しないでください。それらをすべて初期化する場合は、次のようにする必要があります。

public Foo() {
    bar = new Bar[10];
    for (int i = 0; i < 10; i++) {
      bar[i] = new Bar();
    }
    a = bar[0].baz;
}
于 2010-01-24T16:10:40.360 に答える
1

これを試して:

public class Foo 
{
    public int a;
    Bar[] bar = new Bar[10];

    public Foo()
    {
        for (int i = 0; i < 10; ++i)
        {
            this.bar[i] = new Bar();
        }
    }
    a = bar[0].baz();
}

public class Bar 
{
    public int b;


    public int baz() 
    {
        return b;
    }
}
于 2010-01-24T16:11:41.887 に答える
1

直後にBar[] bar = new Bar[10]、バー配列はnull値で初期化されます。したがって、 bar[0]containsnullと呼び出しbar[0].bazは。を引き起こしますNullPointerException

配列に。のようなステートメントを入力する必要がありますbar[0] = new Bar()。または

for (int i = 0; i < bar.length; i++) {
    bar[i] = new Bar();
}
于 2010-01-24T16:15:47.680 に答える
1

ここでの重要な問題は、Javaでの配列の初期化の誤解です。bar[]の初期化は「nullである10個のバー参照」になります。

これは修正された例です(10を使用していません)が、他の理由(パブリックメンバーなど)のためにJavaスタイルはあまり良くありません:

class Foo {
    Bar[] bar = new Bar[] { new Bar(), new Bar() };
    public int a = bar[0].b;
}

public class Bar {
    public int b = 0;

    public static void main(String... args) {
        Foo foo = new Foo();
        System.out.println(foo.a);
    }
}

この例は、Javaの真のスタイルに近いものです。

class Foo {
    static final int numBars = 10;
    private Bar2[] bar = new Bar2[numBars];
    private int a;

    public int getA() { return a; }

    public Foo() {
        for (int i = 0; i < numBars; i++) {
            bar[i] = new Bar2(); 
        } 
        a = bar[0].getB();
    }
}

public class Bar2 {
    private int b = 0;
    public int getB() { return b; }

    public static void main(String... args) {
        Foo foo = new Foo();
        System.out.println(foo.getA());
    }
}
于 2010-01-24T16:24:36.680 に答える
1

から働くための多くの正解。私があなたが持っているかもしれないと思ういくつかの問題:

  • Fooのコンストラクターは、クラス内のどこかにコードを配置するだけでなく、Foo(){/ * ...*/}になります。
  • 自分でループを使用する代わりに、java.util.Arrays.fill(Object [] a、Object val)を使用できます。

そのようです:

public class Foo {
    public int a;
    Bar[] bar = new Bar[10];

    Foo() {
        java.util.Arrays.fill(bar, new Bar());
        a = bar[0].baz();
    }
}

編集:更新された質問については、main(...)メソッドからnew Foo()を呼び出すだけです。また、あなたのように静的コンストラクターを持つことはできません。

于 2010-01-24T16:58:50.767 に答える
1

あなたのコードに対するいくつかの答えとコメント:

コンストラクターはそれ自体では呼び出されません。ステートメントを使用してアクティブに呼び出します。new Foo()

initializeFoo()メソッドはコンパイルされません。メソッドは静的であり、非静的クラスメンバーにアクセスできません(barあなたの場合のように)。

そして最後に、public static void Foo()コンストラクタではなくメソッドです。コンストラクターには戻り型がありません(voidあなたの場合)。

于 2010-01-24T19:21:01.770 に答える