2010-01-24 4 views
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 [] быть нулевым?

EDIT: После некоторых попыток, я, наконец, исправился, спасибо всем! Однако я не мог вызвать конструктор, чтобы исправить ситуацию; Мне пришлось создать еще одну функцию и вызвать эту функцию из 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; 
    } 
} 

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

+0

То же самое, что вы всегда делаете - инициализируйте его, чтобы указать на объект в куче. – duffymo

+0

Если вам нужна помощь в вашем коде, вам нужно будет показать нам код, который действительно вызывает проблему, а не какой-то другой код, который, по вашему мнению, представляет проблему, но пропускает жизненно важные биты и даже не компилируется. –

+0

@Michael Спасибо, я сделаю это в следующий раз – wrongusername

ответ

6

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

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

for(int i=0; i<bar.length; ++i) 
    bar[i]=new Bar(); 
3

Причина вы получаете 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

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

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; 
    } 
} 
+0

'b = 0' в конструкторе избыточно. и жесткое кодирование 10 в двух местах не приятно;) – Bozho

+0

уверен, но это его код. Я просто фиксирую одну проблему за раз. – duffymo

+0

просто напоминая :) – Bozho

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

a = bar[0].baz; 

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

for(int i=0; i<bar.length; i++) { 
    bar[i] = new Bar(); 
} 
+0

спасибо! это сработало, но по какой-то причине я не смог заставить конструктора заставить это работать; Мне пришлось использовать этот код внутри другого метода – wrongusername

1

Сразу после 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

Ключевым вопросом здесь является непонимание array initialization in 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

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

  • Конструктор для Foo будет Foo() {/ * ... * /} не просто размещая код в любом месте в классе.
  • Вместо того, чтобы использовать петлю самостоятельно, вы можете использовать java.util.Arrays.fill (Object [] а, объект Валу)

Как так:

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

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

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

1

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

Конструктор не дозвонился по себе, вы называете это активно с заявлением new Foo()

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

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

Смежные вопросы