Почему int num = Integer.getInteger (123) выдает исключение NullPointerException?

Следующий код выдает NullPointerException:

int num = Integer.getInteger("123");

Вызывает ли мой компилятор getInteger с нулевым значением, поскольку он статичен? В этом нет никакого смысла!

Что происходит?


person user282886    schedule 26.06.2010    source источник
comment
используйте взамен Integer.getValue (). Это сообщение в блоге хорошо объясняет, почему: konigsberg.blogspot .in / 2008/04 /   -  person Pranaysharma    schedule 26.04.2015


Ответы (3)


Большая картинка

Здесь есть две проблемы:

  • Integer getInteger(String) doesn't do what you think it does
    • It returns null in this case
  • the assignment from Integer to int causes auto-unboxing
    • Since the Integer is null, NullPointerException is thrown

Чтобы разобрать (String) "123" на (int) 123, вы можете использовать, например, int Integer.parseInt(String).

использованная литература

Integer Справочные материалы по API


On Integer.getInteger

Вот что говорится в документации о том, что делает этот метод:

_15 _: определяет целочисленное значение системного свойства с указанным именем. Если нет свойства с указанным именем, если указанное имя пустое или null, или если свойство не имеет правильного числового формата, то возвращается null.

Другими словами, этот метод не имеет ничего общего с преобразованием String в значение int/Integer, а скорее связан с _ 20_.

По общему признанию, это может быть большим сюрпризом. К сожалению, в библиотеке есть такие сюрпризы, но она преподает вам ценный урок: всегда ищите документацию, чтобы узнать, что делает метод.

По совпадению, вариант этой проблемы был описан в < em> Возвращение головоломок: Шлок и трепет (TS-5186), презентация технической сессии JavaOne 2009 Джоша Блоха и Нила Гафтера. Вот заключительный слайд:

Мораль

  • Strange and terrible methods lurk in libraries
    • Some have innocuous sounding names
  • If your code misbehaves
    • Make sure you're calling the right methods
    • Прочтите документацию библиотеки
  • For API designers
    • Don't violate the principle of least astonishment
    • Не нарушайте иерархию абстракций
    • Не используйте одинаковые имена для сильно различающегося поведения

Для полноты картины существуют также методы, аналогичные Integer.getInteger:

Связанные вопросы


На автоответчике

Другой вопрос, конечно, заключается в том, как бросить NullPointerException. Чтобы сосредоточиться на этой проблеме, мы можем упростить фрагмент следующим образом:

Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!

Вот цитата из Effective Java 2nd Edition, пункт 49: Предпочитайте примитивные типы упакованным примитивам:

Таким образом, используйте примитивы вместо примитивов в штучной упаковке, когда у вас есть выбор. Примитивные типы проще и быстрее. Если вы должны использовать примитивы в штучной упаковке, будьте осторожны! Автобокс снижает многословие, но не снижает опасность использования упакованных примитивов. Когда ваша программа сравнивает два упакованных примитива с оператором ==, она выполняет сравнение идентичности, что почти наверняка не то, что вам нужно. Когда ваша программа выполняет вычисления смешанного типа с использованием упакованных и распакованных примитивов, она выполняет распаковку, а когда ваша программа выполняет распаковку, она может выбросить NullPointerException. Наконец, когда ваша программа упаковывает примитивные значения, это может привести к созданию дорогостоящих и ненужных объектов.

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

Связанные вопросы

person polygenelubricants    schedule 26.06.2010
comment
Итак, Integer.getInteger(s) примерно эквивалентно Integer.parseInt(System.getProperty(s))? Я думаю, что предпочитаю второй, хотя он более подробный, потому что он подчеркивает тот факт, что вы извлекаете информацию из свойств системы. - person MatrixFrog; 26.06.2010
comment
Как только я опубликовал этот комментарий, я понял, что могу просто посмотреть на фактический источник класса Integer! Я был на правильном пути, за исключением того, что он использует Integer.decode вместо Integer.parseInt, который ищет начальные 0x или 0 для анализа числа как шестнадцатеричного или восьмеричного соответственно. - person MatrixFrog; 26.06.2010
comment
Для тех, кто спрашивает Почему NullPointerException?: programmers.stackexchange.com/questions/158908/ - person Elrond_EGLDer; 28.12.2015
comment
@Oracle, можете ли вы отказаться от java.lang.Integer.getInteger (String), пожалуйста? - person mjaggard; 09.10.2018

Из http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html:

getInteger 'Определяет целочисленное значение системного свойства с указанным именем.'

Вы хотите это:

Integer.parseInt("123")
person Kieren Johnstone    schedule 26.06.2010

Проверьте документацию метода getInteger (). В этом методе параметр String является системным свойством, определяющим целочисленное значение системного свойства с указанным именем. "123" не является именем какого-либо системного свойства, как описано здесь . Если вы хотите преобразовать эту строку в int, используйте метод как int num = Integer.parseInt("123").

person Sonal Patil    schedule 26.06.2010