我想创建一个类Bar
,这样每次实例化Bar
时,它都会被添加到对象ArrayList<Bar>
的{{1}}中。这就是我的尝试:
Foo
我意识到这里发生了什么(构造函数没有完成,所以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
),但我怎么能避免这种情况?
答案 0 :(得分:2)
我意识到这里发生了什么(构造函数没有完成,所以返回null),但是我怎么能避免这种情况?
您的诊断不正确。
this
的值永远不会是null
。这包括在构造函数中。
JLS(15.8.3)声明如下:
“关键字this只能在实例方法或默认方法的主体中使用,或者在类的构造函数的主体中使用,或者在类的实例初始化程序中使用,或者在实例变量的初始化程序中使用如果它出现在其他任何地方,则会发生编译时错误。“
“当用作主表达式时,关键字this表示一个值,该值是对调用实例方法或默认方法的对象(第15.12节)的引用,或者是对正在构造的对象的引用。”
如你所见:
this
关键字只能出现在 当前对象的上下文中,并且
this
的值(当用作表达式时)始终是对当前对象的引用;没有提及任何可能是null
的案例。
(另见:Can "this" ever be null in Java?)
this
引用的对象在该点未完全初始化,但这不是您所看到的异常的原因。 NPE的原因是另一回事。
具体来说,如果NPE被抛出,那么 f
null
或 f.getBars()
正在返回null
。看看你如何编写Foo
类,后者肯定是合理的。 (您没有初始化bars
成员...因此它将是null
。)
答案 1 :(得分: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
班。