Большая картина
Здесь есть две проблемы:
Integer getInteger(String)
не делает то, что, как вы думаете, делает - Возвращается
null
в этом случае
- присваивание от
Integer
до int
вызывает автоматическое распаковывание - , поскольку
Integer
равно null
, NullPointerException
Для анализа (String) "123"
до (int) 123
вы можете использовать, например, int Integer.parseInt(String)
.
Ссылки
Integer
Ссылки API
Вкл. Integer.getInteger
Вот что говорит документация о том, что делает этот метод:
public static Integer getInteger(String nm)
: Определяет целочисленное значение системного свойства с указанным именем.Если нет свойства с указанным именем, если указанное имя пустое или null
, или если свойство не имеет правильный числовой формат, возвращается null
.
Другими словами, этот метод не имеет ничего общего с синтаксическим анализом String
до значения int/Integer
, а скорее он имеет отношение к методу System.getProperty
.
По общему признанию, это может быть довольно неожиданным.К сожалению, у библиотеки есть такие сюрпризы, как это, но она преподает вам ценный урок: всегда ищите документацию, чтобы подтвердить, что метод делает.
По совпадению, вариант этой проблемы был показан в Возвращение головоломок: Шлок и Трепет (TS-5186) , презентация Джоша Блоха и Нила Гафтера в 2009 году на JavaOne.Вот заключительный слайд:
Мораль
- В библиотеках скрываются странные и ужасные методы
- Некоторые имеют безобидные звучащие имена
- Если ваш код плохо себя ведет
- Убедитесь, что вы вызываете правильные методы
- Прочитайте документацию библиотеки
- Для разработчиков API
- Не нарушайте принцип наименьшего удивления
- Не нарушайте иерархию абстракций
- Не используйте похожие имена для дико отличающихся поведений
Для полноты изложения существуют также методы, аналогичные Integer.getInteger
:
Смежные вопросы
При автоматическом подключении
ДругойКонечно, вопрос в том, как бросить NullPointerException
.Чтобы сосредоточиться на этой проблеме, мы можем упростить фрагмент кода следующим образом:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Вот цитата из Effective Java 2nd Edition, Item 49: Предпочтение типов примитивов примитивам в штучной упаковке:
Подводя итог, используйте примитивы вместо коробочных примитивов, когда у вас есть выбор.Примитивные типы проще и быстрее.Если вы должны использовать коробочные примитивы, будьте осторожны!Автобокс уменьшает многословность, но не опасность использования коробочных примитивов.Когда ваша программа сравнивает два коробочных примитива с оператором ==
, она выполняет сравнение идентификаторов, что почти наверняка не то, что вам нужно.Когда ваша программа выполняет вычисления смешанного типа с использованием упакованных и распакованных примитивов, она выполняет распаковку, а когда ваша программа выполняет распаковку, она может выдать NullPointerException
.Наконец, когда ваша программа упаковывает примитивные значения, это может привести к дорогостоящим и ненужным созданиям объектов.
Есть места, где у вас нет выбора, кроме как использовать примитивы в штучной упаковке, например, дженерики, но в противном случае вам следует серьезноподумайте, оправдано ли решение использовать штучные примитивы.
Смежные вопросы