NullPointerException из булева
Это одно для пуристов java, я думаю. Недавно у меня возникла проблема с методом для выполнения пользовательского синтаксического анализа значений String в Boolean. Достаточно простая задача, но по какой-то причине нижеприведенный метод бросал исключение NullPointerException в нулевом случае...
static Boolean parseBoolean(String s)
{
return ("1".equals(s) ? true : ("0".equals(s) ? false : null));
}
Тип возврата для метода является логическим, поэтому почему и как можно исключить NullPointerException?
От отладки через это кажется, что исключение бросается в том месте, где вложенное операторное выражение в строке оценивается как null и возвращает значение null во внешнюю строку в строке, но опять-таки я не могу объяснить, почему.
В конце концов я сдался и переписал метод следующим образом:
static Boolean parseBoolean(String s)
{
if ("1".equals(s)) return true;
if ("0".equals(s)) return false;
return null;
}
Следующий код находится на полпути между двумя, а также работает как ожидалось:
static Boolean parseBoolean(String s)
{
if ("1".equals(s)) return true;
return "0".equals(s) ? false : null;
}
Ответы
Ответ 1
Это также работает:
static Boolean parseBoolean(String s)
{
return ("1".equals(s) ? Boolean.TRUE : ("0".equals(s) ? Boolean.FALSE : null));
}
Итак, причина, по которой вы получаете NPE, связана с автобоксированием, потому что использование boolean
в тройном операторе приводит к тому, что результат выражения обрабатывается как boolean
. И un-бокс null
вызывает NPE.
Ответ 2
Мое предложение? Не возвращайте Boolean
, возвращайте Boolean
и генерируйте исключение:
static boolean parseBoolean(String s)
{
if ("1".equals(s)) return true;
if ("0".equals(s)) return false;
throw new IllegalArgumentException(s + " is not a boolean value.");
}
Принятие подхода, подобного приведенному выше, поможет избежать случайного обращения к объекту null Boolean
.
Посмотрите отличный ответ от NilsH, чтобы узнать, почему ваш оригинальный метод выбрасывает исключение.
Ответ 3
Интересно, но ни один ответ не говорит вам, что почему это происходит в первую очередь.
Это связано с тройственным выражением.
Компилятор интерпретирует нуль как нулевую ссылку на Boolean, применяет правила autoboxing/unboxing для Boolean (на null) = > вы получаете исключение NullPointerException во время выполнения.