Следующий код выдает NullPointerException:
int num = Integer.getInteger("123");
Вызывает ли мой компилятор значение getIntegernull, поскольку оно статично? В этом нет никакого смысла!
Что творится?
Следующий код выдает NullPointerException:
int num = Integer.getInteger("123");
Вызывает ли мой компилятор значение getIntegernull, поскольку оно статично? В этом нет никакого смысла!
Что творится?
Ответы:
Здесь есть две проблемы:
Integer getInteger(String) не делает то, что вы думаете
nullв этом случаеIntegerдо intвызывает автоматическую распаковку
IntegerIS null, NullPointerExceptionброшеноДля того, чтобы разобрать , (String) "123"чтобы (int) 123, вы можете использовать , например int Integer.parseInt(String).
Integer Ссылки APIInteger.getIntegerВот что говорится в документации о том, что делает этот метод:
public static Integer getInteger(String nm): Определяет целочисленное значение системного свойства с указанным именем. Если нет свойства с указанным именем, если указанное имя пусто илиnull, или если свойство не имеет правильного числового формата, тоnullвозвращается.
Другими словами, этот метод не имеет ничего общего с разбора Stringна int/Integerзначение, но , скорее, имеет отношение к System.getPropertyметоду.
По общему признанию, это может быть сюрпризом. К сожалению, в библиотеке есть такие сюрпризы, но она преподает вам ценный урок: всегда ищите документацию, чтобы узнать, что делает метод.
По совпадению, вариация этой проблемы была представлена в « Возвращении головоломок: Шлок и трепет» (TS-5186) , презентации Джоша Блоха и Нила Гафтера на технической сессии JavaOne 2009 года. Вот заключительный слайд:
Мораль
- В библиотеках скрываются странные и ужасные методы
- У некоторых безобидно звучащие имена
- Если ваш код плохо себя ведет
- Убедитесь, что вы вызываете правильные методы
- Прочтите документацию библиотеки
- Для разработчиков API
- Не нарушайте принцип наименьшего удивления
- Не нарушайте иерархию абстракций
- Не используйте одинаковые имена для сильно различающегося поведения
Для полноты картины существуют также эти методы, аналогичные Integer.getInteger:
Другой вопрос, конечно, в том, как NullPointerExceptionего бросают. Чтобы сосредоточиться на этой проблеме, мы можем упростить фрагмент следующим образом:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Вот цитата из Effective Java 2nd Edition, пункт 49: Предпочитайте примитивные типы упакованным примитивам:
Таким образом, используйте примитивы вместо примитивов в штучной упаковке, когда у вас есть выбор. Примитивные типы проще и быстрее. Если вы должны использовать примитивы в штучной упаковке, будьте осторожны! Автобокс снижает многословие, но не снижает опасность использования упакованных примитивов. Когда ваша программа сравнивает два упакованных примитива с
==оператором, она выполняет сравнение идентичности, что почти наверняка не то, что вам нужно. Когда ваша программа выполняет вычисления смешанного типа с использованием упакованных и распакованных примитивов, она выполняет распаковку, а когда ваша программа выполняет распаковку, она может выброситьNullPointerException. Наконец, когда ваша программа упаковывает примитивные значения, это может привести к созданию дорогостоящих и ненужных объектов.
Есть места, где у вас нет выбора, кроме как использовать упакованные примитивы, например дженерики, но в противном случае вам следует серьезно подумать, оправдано ли решение использовать упакованные примитивы.
Integer.getInteger(s)примерно эквивалентно Integer.parseInt(System.getProperty(s))? Я думаю, что предпочитаю второй, хотя он более подробный, потому что он подчеркивает тот факт, что вы извлекаете информацию из свойств системы.
Integer.decodeвместо Integer.parseInt, который ищет начало 0xили 0анализирует число как шестнадцатеричное или восьмеричное, соответственно.
NullPointerException? : programmers.stackexchange.com/questions/158908/…
С http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html :
getInteger 'Определяет целочисленное значение системного свойства с указанным именем.'
Вы хотите это:
Integer.parseInt("123")
Пожалуйста, проверьте документацию метода getInteger () . В этом методе Stringпараметр является системным свойством, определяющим целочисленное значение системного свойства с указанным именем. «123» - это не имя какого-либо системного свойства, как здесь обсуждается . Если вы хотите преобразовать эту строку в int, используйте метод как
int num = Integer.parseInt("123").