Ответ 1
Большое изображение
Здесь есть две проблемы:
-
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
.
По общему признанию, это может быть весьма неожиданным. К сожалению, библиотека имеет такие сюрпризы, но она учит вас ценному уроку: всегда смотрите документацию, чтобы подтвердить, что делает метод.
В обоих случаях вариация этой проблемы была представлена в Возвращение головоломок: Шлока и Awe (TS-5186), Джош Блох и Нил Gafter 2009 JavaOne Техническая сессия. Здесь завершающий слайд:
Мораль
- Странные и ужасные методы скрываются в библиотеках
- У некоторых есть безобидные звуковые имена
- Если ваш код неверно работает
- Убедитесь, что вы вызываете правильные методы.
- Прочитайте документацию библиотеки
- Для разработчиков API
- Не нарушайте принцип наименьшего удивления.
- Не нарушать иерархию абстракции
- Не используйте похожие имена для совершенно разных поведений.
Для полноты существуют также эти методы, аналогичные Integer.getInteger
:
Связанные вопросы
- Самое удивительное нарушение принципа наименьшего удивления
- Самый неудобный/вводящий в заблуждение метод в Java Base API?
В режиме autounbing
Другой проблемой, конечно же, является то, как бросается NullPointerException
. Чтобы сосредоточиться на этой проблеме, мы можем упростить фрагмент следующим образом:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Здесь цитата из Effective Java 2nd Edition, пункт 49: Предпочитают примитивные типы для примитивов в штучной упаковке:
В общем, используйте примитивы, предпочитая вложенные в бокс примитивы, когда у вас есть выбор. Примитивные типы проще и быстрее. Если вы должны использовать примитивы в штучной упаковке, будьте осторожны! Автобоксинг уменьшает многословие, но не опасность использования примитивов в штучной упаковке. Когда ваша программа сравнивает два вставных примитива с оператором
==
, это делает сравнение идентичности, которое почти наверняка не то, что вы хотите. Когда ваша программа выполняет смешанные вычисления с использованием примитивов с боксами и unboxed, она распаковывается, а когда ваша программа распаковывается, она может бросатьNullPointerException
. Наконец, когда ваши программные коды приносят примитивные значения, это может привести к дорогостоящим и ненужным созданиям объектов.
Есть места, где у вас нет выбора, кроме как использовать вставные примитивы, например. дженериков, но в противном случае вам следует серьезно подумать, оправдано ли решение использовать примитивы в штучной упаковке.
Связанные вопросы
- В чем разница между int и Integer в Java/С#?
- Почему автобоксинг в Java позволяет мне иметь 3 возможных значения для логического?
- Гарантируется ли, что новый Integer (i) == я в Java? (YES!!!)
- При сравнении двух целых чисел в Java происходит автоматическое разблокирование? (НЕТ!!!)
- Java noob: generics over objects only? (да, к сожалению)