Ответ 1
Проблема заключается в том, что метод String.valueOf
перегружен:
Язык спецификации Java указывает, что в этих случаях выбирается наиболее специфическая перегрузка:
JLS 15.12.2.5 Выбор наиболее конкретного метода
Если более чем один метод-член доступен и применим к вызову метода, необходимо выбрать его для предоставления дескриптора для отправки времени выполнения. Язык программирования Java использует правило, в котором выбран наиболее специфический метод.
A char[]
is-an Object
, но не все Object
is-a char[]
. Поэтому char[]
более специфичен, чем Object
, и, как указано языком Java, в этом случае выбирается перегрузка String.valueOf(char[])
.
String.valueOf(char[])
ожидает, что массив будет не null
, а так как null
задан в этом случае, он затем бросает NullPointerException
.
Легкое "исправление" заключается в том, чтобы явно выразить null
на Object
следующим образом:
System.out.println(String.valueOf((Object) null));
// prints "null"
Связанные вопросы
Мораль истории
Есть несколько важных из них:
- Эффективное Java 2nd Edition, пункт 41: разумно использовать перегрузку
- Просто потому, что вы можете перегружать, не означает, что вы должны каждый раз
- Они могут вызвать путаницу (особенно если методы имеют дико разные вещи)
- Используя хорошую среду IDE, вы можете проверить, какая перегрузка выбрана во время компиляции
- С Eclipse вы можете навести курсор мыши на вышеупомянутое выражение и увидеть, что действительно выбрана перегрузка
valueOf(char[])
!
- С Eclipse вы можете навести курсор мыши на вышеупомянутое выражение и увидеть, что действительно выбрана перегрузка
- Иногда вы хотите явно лить
null
(примеры следовать)
См. также
При отливке null
Существует, по крайней мере, две ситуации, когда необходимо явно указать null
на конкретный ссылочный тип:
- Чтобы выбрать перегрузку (как указано в приведенном выше примере)
- Чтобы дать
null
как единственный аргумент параметра vararg
Простым примером последнего является следующее:
static void vararg(Object... os) {
System.out.println(os.length);
}
Тогда мы можем иметь следующее:
vararg(null, null, null); // prints "3"
vararg(null, null); // prints "2"
vararg(null); // throws NullPointerException!
vararg((Object) null); // prints "1"
См. также
- Руководство по языку Java/varargs - чтобы понять, как это реализовано