Можно ли в тернарном операторе Java оценить первый аргумент, даже если выражение привело к ложному значению?

Я недавно обнаружил необычную ошибку в своем коде в ходе случайного специального тестирования. Итак, я сделал для него тестовый пример.

Вот мой тестовый пример:

 SampleRequest request = new SampleRequest();
    request.setA(null);
    request.setB(null);
    assertEquals(null, request.getAOrB());

A и B определены как типы java.lang.Integer и имеют прямые методы установки для установки своих значений в запрос.

Также есть перечисление. Он имеет примитивное целочисленное значение и метод, который используется в этом коде. Я размещу здесь соответствующие фрагменты:

enum Swapper {
public int c;
Swapper findSwapperToUse(final int a) {
   for(Swapper swapper : values()) {
       if(swapper.c == a) {
          return swapper;
       }
   }
   return null;
}
}

Вот метод, который сбивает с толку. Вызов тестового метода для этого метода приводит к NPE, но в последней строке метода.

    public class SampleRequest {
    private Integer A;
    private Integer B;

    public void setA(final Integer A) {
        this.A = A;
    }

    public void setB(final Integer B) {
        this.B = B;
    }


public Integer getAOrB() {
    return A != null ? Swapper.findSwapperToUse(A).c
         : B;
}
}

В тесте для A и B установлено значение NULL. Следовательно, A! = Null возвращает false. Однако я получаю исключение NullPointerException в номере строки для строки: B.

Я предполагаю, что по какой-то причине оценивается первое выражение Swapper.findSwapperToUse (A) .c, и поэтому A.intValue ( ) вызывается через автобоксирование, в результате чего возникает исключение NullPointerException для нулевого значения. В процессе отладки известно, что findSwapperToUse () не вызывается.

Однако, согласно этому вопросу, этого не должно происходить: оба A и B имеют значение null. Следовательно, A! = Null возвращает false. Однако я получаю исключение NullPointerException в номере строки для строки: B.

Я предполагаю, что по какой-то причине оценивается первое выражение Swapper.findSwapperToUse (A) .c, и поэтому A.intValue ( ) вызывается через автобоксирование, в результате чего возникает исключение NullPointerException для нулевого значения. В процессе отладки известно, что findSwapperToUse () не вызывается.

Однако, согласно этому вопросу, этого не должно происходить: оба A и B имеют значение null. Следовательно, A! = Null возвращает false. Однако я получаю исключение NullPointerException в номере строки для строки: B.

Я предполагаю, что по какой-то причине оценивается первое выражение Swapper.findSwapperToUse (A) .c, и поэтому A.intValue ( ) вызывается через автобоксирование, в результате чего возникает исключение NullPointerException для нулевого значения. В процессе отладки известно, что findSwapperToUse () не вызывается.

Однако, согласно этому вопросу, этого не должно происходить: Тернарное вычисление Java (немедленное выполнение)

Невыбранное выражение операнда не оценивается для данной конкретной оценки условного выражения.

Возврат значения NULL (B) не приведет к исключению NullPointerException - это прекрасно, если вернуть здесь нулевой результат.

Что, черт возьми, происходит?

РЕДАКТИРОВАТЬ: Я забыл добавить, что я изменил код, чтобы избежать этого, используя прямой оператор if - следующий код работает должным образом:

public Integer getAOrB() {
    if(A != null) {
        return Swapper.findSwapperToUse(A).c;
    }
    return B;
}

13
задан Community 23 May 2017 в 12:01
поделиться