Java: исключение null-указателя при распаковке Integer?

Этот код вызывает исключение нулевого указателя. Я понятия не имею, почему:

private void setSiblings(PhylogenyTree node, Color color) throws InvalidCellNumberException {
    PhylogenyTree parent = node.getParent();

    for (PhylogenyTree sibling : parent.getChildren()) {
        if (! sibling.equals(node)) {
            Animal animal = sibling.getAnimal();
            BiMap<PhylogenyTree, Integer> inverse = cellInfo.inverse();
            int cell = inverse.get(animal); // null pointer exception here
            setCellColor(cell, color);
        }
    }
}

Я изучил его в отладчике, и все локальные переменные не равны нулю. Как еще это могло произойти? BiMap из коллекций Google.

Ответ 1

Исключение нулевого указателя является результатом распаковки результата inverse.get(animal). Если inverse не содержит ключа animal, он возвращает null, "типа" Integer. Учитывая, что назначение относится к ссылке int, Java освобождает значение в int, что приводит к исключению нулевого указателя.

Вы должны либо проверить inverse.containsKey(animal), либо использовать Integer в качестве типа локальной переменной, чтобы избежать нежелательной отправки и действовать соответствующим образом. Правильный механизм зависит от вашего контекста.

Ответ 2

Проверьте inverse.containsKey(animal), BiMap<PhylogenyTree, Integer>. Обратное может не иметь животных.

Ответ 3

Вы должны иметь трассировку стека. Это точно говорит, что это была за черта, где это произошло. Отправьте это, и мы можем сказать.

Из всего опубликованного кода я могу "догадаться", что одним из них является потенциальное исключение NullPointerException (NPE).

node может быть нулевым и вызывать node.getParent.

Родитель узла может быть нулевым, и parent.getChildren может вызвать NPE.

Один из братьев и сестер может быть нулевым и sibling.equals могут бросить NPE.

cellInfo может быть нулевым, а cellInfo.inverse его выбросит.

Наконец, возвращаемое значение может быть нулевым, и inverse.get() его выбросит.

Уф... !!

Итак, чтобы избежать этих диких предположений, почему бы вам просто не опубликовать свою трассировку стека, и мы узнаем?

Это должно что-то вроде:

 java.lang.NullPointerException: null
 at YourClass.setSiblings( YouClass.java:22 )
 at YourClass.setSiblng( YourClass.java: XX )

так далее...