Reputation: 34569
I want to create a class Bar
such that every time I instantiate a Bar
, it is added to an ArrayList<Bar>
of an object Foo
. This is what I have tried:
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!
}
}
I realize what is happening here (the constructor is not finished, so this
returns null
), but how can I avoid this?
Upvotes: 0
Views: 998
Reputation: 719229
I realize what is happening here (the constructor is not finished, so this returns null), but how can I avoid this?
Your diagnosis is incorrect.
The value of this
can never be null
. And that includes in a constructor.
The JLS (15.8.3) states the following:
"The keyword this may be used only in the body of an instance method or default method, or in the body of a constructor of a class, or in an instance initializer of a class, or in the initializer of an instance variable of a class. If it appears anywhere else, a compile-time error occurs."
"When used as a primary expression, the keyword this denotes a value that is a reference to the object for which the instance method or default method was invoked (§15.12), or to the object being constructed."
As you can see:
the this
keyword can only appear in a context in where there is a current object, and
the value of this
(when used as an expression) is always the reference to the current object; there is no mention of any case where it could be null
.
(See also: Can "this" ever be null in Java?)
The object that this
refers to is not fully initialized at that point, but that isn't the cause of the exception you are seeing. The cause of the NPE is something else.
Specifically, if an NPE is being thrown at that line, then either f
is null
or f.getBars()
is returning null
. And looking at how you have coded the Foo
class, the latter is definitely plausible. (You don't initialize the bars
member ... so it will be null
.)
Upvotes: 2
Reputation: 877
Because bars
is not initialized, whenever you call f.getBars()
it returns a null
object. When you try to call .add()
on a null
object, you get a NullPointerException
.
Change
private ArrayList<Bar> bars;
to
private ArrayList<Bar> bars = new ArrayList<Bar>();
or add
public Foo(){this.bars = new ArrayList<Bar>();}
to your Foo
class.
Upvotes: 0