Неожиданное исключение NullPointerException при автоупаковке/распаковке длинного типа java в качестве возвращаемого значения

Может кто-нибудь объяснить, почему метод getY() вызывает исключение NullPointerException.

public class NullTest {
    private String s = "";

    public Long getValue() {
        return null;
    }

    public Long getX() {
        return s != null ? getValue() : new Long(0);
    }

    public Long getY() {
        return s != null ? getValue() : 0L;
    }

    public static void main(String[] args) {
        NullTest nt = new NullTest();
        System.out.println("x = " + nt.getX());
        System.out.println("y = " + nt.getY());
    }
}

Пример вывода:

x = null
Exception in thread "main" java.lang.NullPointerException
    at NullTest.getY(NullTest.java:13)
    at NullTest.main(NullTest.java:19)

person Muhammad Towfique Imam    schedule 11.03.2019    source источник


Ответы (1)


Тип выражения s != null ? getValue() : 0Llong, а не Long. Следовательно, если s != null истинно, а getValue() равно null, при попытке распаковать null в long выдается NullPointerExcetpion.

Вы не получаете эту проблему в getX(), поскольку в выражении s != null ? getValue() : new Long(0) и getValue(), и new Long(0) являются Long, поэтому тип выражения Long, и распаковка не происходит.

person Eran    schedule 11.03.2019
comment
Если я заменю getValue() на null в getY(), исключение не будет выдано. Тип выражения для этого случая длинный, но исключение не выдается. вернуть s != ноль? ноль: 0 л; - person Muhammad Towfique Imam; 11.03.2019
comment
@MuhammadTowfiqueImam существуют разные правила, когда одним из операндов является null. Вы можете увидеть сводные таблицы правил здесь: docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25 - person Eran; 11.03.2019