Почему String.valueOf (null) бросает исключение NullPointerException?
согласно документации, метод String.valueOf(Object obj)
возвращает:
если аргумент
null
, затем строка, равная"null"
; в противном случае-значениеobj.toString()
возвращается.
но почему когда я пытаюсь сделать это:
System.out.println("String.valueOf(null) = " + String.valueOf(null));
он бросает NPE вместо этого? (попробуйте сами если не верите!)
Exception in thread "main" java.lang.NullPointerException at java.lang.String.(Unknown Source) at java.lang.String.valueOf(Unknown Source)
почему это происходит? Документы лгут мне? Это главная ошибка в Ява?
3 ответов
проблема в том, что String.valueOf
метод перегружен:
Java Specification Language мандаты, что в таких случаях, самая специфическая перегрузка - это:
JLS 15.12.2.5 выбор наиболее конкретного метода
если доступно более одного метода элемента и применимо к вызову метода, необходимо выбрать один, чтобы предоставить дескриптор для отправки метода времени выполнения. Язык программирования Java использует правило, что наиболее специфичные метод.
A char[]
и Object
, но не все Object
is-a char[]
. Следовательно,char[]
is более конкретную чем 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 - чтобы понять, как это реализовано
вопросы
проблема в том, что ты называешь String.valueOf(char[])
и не String.valueOf(Object)
.
причина этого в том, что Java всегда будет выбирать наиболее конкретную версию перегруженного метода, который работает с предоставленными параметрами. null
- допустимое значение Object
параметр, но это также допустимое значение для
ошибка с номером 4867608 был подан на этот путь еще в 2003 году, который был разрешен как "не исправит" с этим объяснением.
мы не можем изменить из-за ограничений совместимости. Обратите внимание, что это метод public static String valueOf (char data []), который заканчивается вызывается, и в нем не упоминается замена "null" для аргументы null.
@###.### 2003-05-23