2015-09-24 2 views
3

Я просто нашел что-то интересное.valueOf метод String возвращает 4 при передаче пустой строки

public class test { 

    public static void main(String a[]) 
    { 
     System.out.println(String.valueOf(null).length()); 
    } 

} 

Выход

Exception in thread "main" java.lang.NullPointerException 
    at java.lang.String.<init>(Unknown Source) 

Это то, что я отчасти ожидал.

Но когда я запускаю этот

public class test { 

    public static void main(String a[]) 
    { 
     String s=null; 
     System.out.println(String.valueOf(s).length()); 
    } 

} 

Выход

4 

Есть две перегружен версии valueOf, который будет вызван, они

/** 
    * Returns the string representation of the <code>Object</code> argument. 
    * 
    * @param obj an <code>Object</code>. 
    * @return if the argument is <code>null</code>, then a string equal to 
    *   <code>"null"</code>; otherwise, the value of 
    *   <code>obj.toString()</code> is returned. 
    * @see  java.lang.Object#toString() 
    */ 
    public static String valueOf(Object obj) { 
    return (obj == null) ? "null" : obj.toString(); 
    } 

    /** 
    * Returns the string representation of the <code>char</code> array 
    * argument. The contents of the character array are copied; subsequent 
    * modification of the character array does not affect the newly 
    * created string. 
    * 
    * @param data a <code>char</code> array. 
    * @return a newly allocated string representing the same sequence of 
    *   characters contained in the character array argument. 
    */ 
    public static String valueOf(char data[]) { 
    return new String(data); 
    } 

Я не понимаю, почему Метод valueOf (Object s) дает специальное обращение к null. Мысли/Комментарии?

+0

Поскольку найден наилучший подходящий метод и его обработка. Даже если вы устанавливаете String s равным null, вы объявили строку, которая занимает память. Вот почему вы получаете вывод как 4. # –

+4

Я думаю, что реальный вопрос здесь не в том, почему вывод 4 или NPE выбрасывается, но почему оба метода действуют по-разному, учитывая значение null как параметр. – Tunaki

+0

Я вроде согласен с Tunaki, почему эта разница при задании значения null как параметра. –

ответ

3

Проблема заключается в логике вызова метода JLS.

JLS's Choosing the Most Specific Method состояния,

Если более чем один метод член является одновременно доступным и применим к вызову метода, необходимо выбрать один, чтобы предоставить дескриптор метода времени выполнения отправки. Язык программирования Java использует правило, что выбран наиболее специфический метод.

Теперь, в первом случае, когда вы проходите null непосредственно,

System.out.println(String.valueOf(null).length()); 

Оба String.valueOf(Object) и String.valueOf(char[]) применимы ... Так что он использует наиболее специфический метод который является char[].

Неофициальная интуиция заключается в том, что один метод более конкретный, чем другой, если любой вызов, обработанный первым методом, может быть передан другому, без ошибки времени компиляции.

Но в вашем втором случае вы фактически проходите мимо String, хотя это значение равно null.

Применяется только String.valueOf(Object).

+0

Мы можем помочь компилятору выбрать метод * safe *, явно указав, какую перегруженную версию мы интересуем. Мы можем сделать это, набрав 'null' для определенного типа, например' String.valueOf ((String) null) ', который будет вызывать' valueOf (Объект) '. – Pshemo

2

От valueOf Docs

если аргумент имеет нулевое значение, то строка равна "нулю"; в противном случае возвращается значение obj.toString().

Смежные вопросы