2015-01-24 2 views
0

Я хочу создать класс Bar таким образом, что каждый раз, когда я экземпляр Bar, он добавляется к ArrayList<Bar> объекта Foo. Это то, что я пробовал:Использование «это» в конструкторах без бросать NullPointerException

class Foo { 
    private ArrayList<Bar> bars; 
    . 
    . 
    . 
    public ArrayList<Bar> getBars() { return bars; } 
} 

//in class Bar 
class Bar { 
    public Bar(Foo f) { 
     f.getBars().add(this); //NullPointerException! 
    } 
} 

Я понимаю, что здесь происходит (конструктор не закончена, поэтому this возвращается null), но как я могу избежать этого?

+0

Проблема не в этом. Проблема в том, что бары не инициализируются. Do bars = new ArrayList (); сначала в классе Foo (например, в его конструкторе). – Dyrborg

ответ

2

Я понимаю, что здесь происходит (конструктор не закончен, поэтому он возвращает null), но как я могу избежать этого?

Ваш диагноз неверен.

Значение this не может быть null. И это включает в себя конструктор.

JLS (15.8.3) говорится следующее:

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

«При использовании в качестве основного выражения ключевое слово this обозначает значение, которое является ссылкой на объект, для которого был вызван метод экземпляра или метод по умолчанию (§15.12), или к объекту, который создается».

Как вы можете видеть:

  1. this ключевое слово может появляться только в контексте, в котором есть является текущий объект, и

  2. значение this (при использовании как выражение) всегда является ссылкой на текущий объект; нет упоминания о любом случае, где это может быть null.

(Смотри также: Can "this" ever be null in Java?)


Объект, который this относится к не полностью инициализирован в этой точке, но это не является причиной исключения вы видите. Причиной NPE является что-то другое.

В частности, если NPE выбрасывают на этой линии, то либоf является nullилиf.getBars() возвращается null. И глядя на то, как вы кодировали класс Foo, последний определенно правдоподобен. (Вы не инициализируете участника bars ... так что это будет null.)

0

Потому что bars не инициализируется, когда вы звоните f.getBars(), он возвращает объект null. Когда вы пытаетесь позвонить .add() на объект null, вы получите NullPointerException.

Изменить

private ArrayList<Bar> bars; 

в

private ArrayList<Bar> bars = new ArrayList<Bar>(); 

или добавить

public Foo(){this.bars = new ArrayList<Bar>();} 

к вашему Foo класса.

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