So I know I MAY have a null List (ArrayList, specifically). Now a simple check for it like that actually throws a NullPointerException when I’m already checking for it. This one has me stumped since I’ve always used it successfully but I’m sure I’m missing something:
public class MyPost {
private int id;
private List<Label> labels;
public MyPost(int id){ this.id = id }
//getter setters for both plus this added method:
public void addLabel(Label aLabel)
{
if(labels == null)
labels = new ArrayList<Label>();
labels.add(aLabel);
}
}
Now in another part of my code I am iterating over the list of ID’s sent by the client. For simplicity assume that a loop variable ‘i’ is supplying the ids
MyPost aPost = new MyPost(i);
In my logic I may or may not add labels to the post. So at the end before proceeding I check for existence of labels like that:
if(aPost.getLabels()!=null)
//process labels
Now this throws a null pointer exception if nothing was ever added to the list of labels! But that’s exactly what I want to check for and am still getting an NPE!!!
I know aPost.getLabels() IS null if nothing is ever added to it. But the comparison seems to fail and throw an NPE. How to address this issue? Just has me stumped!
UPDATE:
Here is the get label code. Just a trivial getter…
public List<Label> getLabels() { return labels;}
We noticed something that we overlooked before. I’m sure java used to “short circuit” it’s if-conditions i.e., in an OR condition if the first condition evaluated to true it wouldn’t check the second one (similar short-circuiting for AND if the first condition evaluated to false). I am not entirely sure if that is the cause but here’s the if-clause:
if(aPost.getLabels()!=null || !aPost.getLabels().isEmpty())
//process labels
If the list is indeed null short-circuiting shouldn’t evaluate the second condition, correct?? It seems that may be the cause, but we are still testing it out. Just a hunch for now…
In general the first thing you do when you debug an NPE is to examine the stack trace closely and identify the exact line it is thrown from.
The next step is to check all the values that are on the left side of a dereferencing operator (
.) on that line. Another source of NPEs is the new flavour offorloops, and the third one is auto-unboxing, As far as I know, there are no other constructs that inherently throw an NPE, although of course there can always be code that throws it explicitly.All this means that without the stack trace and the complete code we can only guess too.
(Alternatively, if you’re using an IDE you can simply set an exception breakpoint and examine the runtime values of your variables at the moment the NPE is being thrown. But you should be able to find an NPE by offline analysis of the code and the stack trace. It’s an important skill.)
Update: Looking at the updated question it’s obvious that the if statement is wrong. It should read:
OR isn’t the correct operation there, since you want
aPost.getLabels()to be not null AND not to be empty. Java does indeed stop boolean expression evaluation as soon as the value is known, but in your original expression this wasn’t the case ifaPost.getLabels()was null.