Почему 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