2

I have an Android app that is recently published, and I'm receiving crash reports from Google Play Console. One of the crashes is strange. It happens in code similar to the following:

private final List<Item> items = new ArrayList<>();

public void addItem(Item item) {
    items.add(item);  // NullPointerException here!!
}

Apparently items is null when addItem is called, but it seems to me that it's impossible—I've initialized it at the declaration site. I can't imagine a situation in which this could happen, yet it happens a lot. Any idea?

Ryan M
  • 18,333
  • 31
  • 67
  • 74
ycsun
  • 1,825
  • 1
  • 13
  • 21
  • 2
    Is the list really an `ArrayList`? It could also be that `item` is null and the list does not accept null elements (`ArrayList` does accept null though). – M A Feb 24 '21 at 10:04
  • 2
    Please post the exception trace, and if you can the class code, and the Item class code. – Roie Shlosberg Feb 24 '21 at 10:08
  • @MA It really is an `ArrayList`. – ycsun Feb 24 '21 at 10:27
  • @RoieShlosberg Sorry I can't post the code because of the NDA, but the very first line of the stack trace points to the `items.add(item)` line. – ycsun Feb 24 '21 at 10:30
  • Try checking the places where you call addItem. One thing that comes to mind is that you might be calling it from a constructor before items is initialized. – Max Glukhov Feb 24 '21 at 10:53
  • @MaxGlukhov From what I know instance fields are initialized before constructor anyway, that shouldn't cause the problem. – Amongalen Feb 24 '21 at 13:58
  • @Amongalen You are right, I was confusing with Kotlin, order matters there. EDIT: I am referring to init blocks – Max Glukhov Feb 24 '21 at 14:20
  • Does this answer your question? [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – pppery Feb 24 '21 at 23:55
  • @pppery it seems fairly clear from the phrasing of the question that the author understands NPEs in general, but is struggling to understand why it would happen **despite** having initialized the variable. I've given an answer explaining how this could happen. – Ryan M Feb 25 '21 at 04:54

1 Answers1

1

Alright, psychic debugging time. The only way this could happen is if something is calling it as part of the object init, either during setup of other variables or an explicit init { ... } block.

You are almost certainly doing something like this elsewhere in the code:

import java.util.*;

class Main {
    private static class Item { }
    
    private final Item firstItem = setUpItemsAndReturnFirst();
    private final List<Item> items = new ArrayList<>();

    public void addItem(Item item) {
        items.add(item);  // NullPointerException here!!
    }
    
    private Item setUpItemsAndReturnFirst() {
        Item first = new Item();
        Item second = new Item();
        addItem(first);
        addItem(second);
        return first;
    }
    
    public static void main(String args[]) { 
        new Main();
    } 
}

This contains your sample code, and will crash on that line with a NullPointerException, because setUpItemsAndReturnFirst() is being called before items is initialized when it's used to initialize firstItem.

I assume it's behind some sort of conditional, in your case, since it presumably doesn't crash every time or you'd never have released it. But this is the general idea.

Ryan M
  • 18,333
  • 31
  • 67
  • 74
  • Note that giving the stack trace would allow for confirmation of whether this is the case. – Ryan M Feb 25 '21 at 04:57
  • I'm not sure it's what happened in my app, but it nicely answers my question in its current form. Thank you! And sorry I'm unable to figure out a plausible way to show more details in the question. – ycsun Feb 26 '21 at 10:02