Как мне инициализировать объект класса? - PullRequest
3 голосов
/ 24 января 2010

Мой код выглядит примерно так:

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. Как я могу предотвратить пустоту бара []?

РЕДАКТИРОВАТЬ: После некоторой возни я наконец-то исправил, спасибо всем! Однако я не мог вызвать конструктор, чтобы все исправить; Мне пришлось создать другую функцию и вызвать эту функцию из 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;
    }
}

Кто-нибудь хочет помочь мне с этим, или я должен создать другой вопрос? :)

Ответы [ 8 ]

8 голосов
/ 24 января 2010
Bar[] bar = new Bar[10];

a = bar[0].baz;

Приведенное выше создает массив типа Bar, но не заполняет его какими-либо фактическими объектами Bar. Массивы ссылочных типов инициализируются нулевыми ссылками. Вам нужно сделать это:

for(int i=0; i<bar.length; i++) {
    bar[i] = new Bar();
}
6 голосов
/ 24 января 2010

Вы выделили память для ссылок, написав это Bar[] bar = new Bar[10];, но кто будет выделять память для элементов массива? Фактические массивы ссылочных типов инициализируются нулевыми ссылками.

Вам также необходимо выделить память для элементов массива:

for(int i=0; i<bar.length; ++i)
   bar[i]=new Bar();
3 голосов
/ 24 января 2010

Причина, по которой вы получаете исключение NullPointerException, заключается в следующей строке:

a = bar[0].baz;

bar[0] еще не существует.

Что происходит, когда инициализируется Foo, запускаются инициализаторы по умолчанию (как указано выше). Вы создаете bar как массив Bar ссылок, но не инициализируете отдельные места в массиве. Если вы хотите, чтобы все они были инициализированы, вам нужно сделать что-то вроде этого:

public Foo() {
    bar = new Bar[10];
    for (int i = 0; i < 10; i++) {
      bar[i] = new Bar();
    }
    a = bar[0].baz;
}
1 голос
/ 24 января 2010

Некоторые ответы и комментарии к вашему коду:

Конструктор не вызывается сам по себе, вы вызываете его активно с помощью оператора new Foo()

Ваш initializeFoo() метод не компилируется. Метод является статическим и не может получить доступ к нестатическому члену класса (например, bar в вашем случае).

И, наконец, public static void Foo() не конструктор, а метод. Конструктор не имеет возвращаемого типа (void в вашем случае).

1 голос
/ 24 января 2010

Много правильных ответов для работы. Некоторые проблемы, которые, я думаю, у вас могут быть:

  • Конструктор для 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();
    }
}

Изменить: Для вашего обновленного вопроса, просто позвоните новый Foo () от твоего главный(...) метод. Кроме того, у вас не может быть статического конструктора, как у вас.

1 голос
/ 24 января 2010

Ключевой проблемой здесь является неправильное понимание инициализации массива в Java . Инициализация bar [] будет иметь значение «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());
    }
}
1 голос
/ 24 января 2010

Сразу после Bar[] bar = new Bar[10] ваш массив баров инициализируется нулевыми значениями. Таким образом, bar[0] содержит null, и вызов bar[0].baz вызовет NullPointerException.

Вам необходимо заполнить ваш массив оператором типа bar[0] = new Bar(). Или

for (int i = 0; i < bar.length; i++) {
    bar[i] = new Bar();
}
1 голос
/ 24 января 2010

Попробуйте это:

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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...