Тернарный оператор всегда был способом написания, который был под рукой у многих разработчиков.Он упрощает раздутое написание if-else и заменяет его строкой кода, которая невидимо выглядит как шоу.Как всем известно, в таком красивом коде скрывается и ошибка.
причина
Накануне вечером была выпущена функция, которую я считал спокойным требованием, но на следующий день kibana произвела тонны журналов NPE. Большинство этих журналов NPE указывают на строку кода, которую я написал.Я сразу же снял очки и начал исследовать.
код проблемы
Журнал стека Kibana находится в строке 899.
resultMap.put("unAuditPurchaseOrder", switchConf == null ? 0 : switchConf.getUnAuditPurchaseOrder());
1. Проверил resultMap, он инстанцируется на нем и не может быть пустым.
2. Проверьте switchConf, но здесь ошибки нет и сообщения об ошибке не будет.
Вот как дело? ? ? ?
продолжать расследование
Поскольку вы не можете увидеть это невооруженным глазом, вы можете найти только тестовую машину и использовать Артаса, чтобы увидеть конкретную ситуацию. (Используйте с осторожностью онлайн, потому что это может привести к задержке)
trace com.aaa.bbb.ccc.ddd.eee.CustomerButtonService getPurchaseConfig -n 5 '1==1' --skipJDKMethod false
Конечно же, ключ был найден здесь.
Здесь intValue() действительно выполняется! То есть, если
switchConf.getUnAuditPurchaseOrder()
Это null, тогда, очевидно, произошел NPE.
Взгляните на байт-код
Для того, чтобы показать эффект, я перешел на простую программу
public class Test {
public static void main(String[] args) {
Integer i = null;
System.out.println(1 != 1 ? 0 : i);
}
}
Перейдите в каталог файла класса и выполните
javap -c -l Test
Затем я снова изменил программу
public class Test {
public static void main(String[] args) {
Integer i = null;
System.out.println(1 == 1 ? 0 : i);
}
}
Это выполняется без ошибок, взгляните на его инструкции JVM:Потому что результатом тернарного оператора является логика первого, который возвращает константу 0.
объяснять
Из приведенных выше экспериментов видно, что когда JVM интерпретирует тернарный оператор, она проверяет тип данных двух логических операторов, и основной тип данных должен иметь преимущественную силу. В эксперименте тип данных является базовым типом данных, поэтому, если логика перейдет к последнему, он будет автоматически распакован. Эта неявная операция является причиной этой ошибки.
решать
Теперь, когда вы знаете причину, просто унифицируйте типы данных:
public class Test {
public static void main(String[] args) {
Integer i = null;
System.out.println(1 != 1 ? new Integer(0) : i);
}
}
Затем, как обычно, давайте взглянем на его инструкции JVM:
Дополнения
Позже я случайно обнаружил, что этот пример также был записан в «Руководстве по разработке Alibaba».На самом деле это одно и то же!
следовать за
В итоге, хоть проблема и была решена, я все равно попал в черный список тестовых одноклассников.