Dlaczego ciągnie.valueOf (null) throw a NullPointerException?

Zgodnie z dokumentacją, metoda String.valueOf(Object obj) zwraca:

Jeśli argumentem jest null, to łańcuch równy "null"; w przeciwnym razie zwracana jest wartość obj.toString().

Ale jak to się dzieje, gdy próbuję to zrobić:

System.out.println("String.valueOf(null) = " + String.valueOf(null));

Zamiast tego rzuca NPE? (spróbuj sam, jeśli nie wierzysz!)

    Exception in thread "main" java.lang.NullPointerException
    at java.lang.String.(Unknown Source)
    at java.lang.String.valueOf(Unknown Source)
Jak to się dzieje? Czy dokumentacja mnie okłamuje? Czy to poważny błąd w Javie?
Author: polygenelubricants, 2010-06-28

3 answers

Problem polega na tym, że String.valueOf metoda jest przeciążona :

Język specyfikacji Javy nakazuje, aby w tego typu przypadkach wybrano najbardziej specyficzne przeciążenie :

JLS 15.12.2.5 wybór najbardziej konkretnej metody

Jeśli więcej niż jedna metoda jest dostępna i ma zastosowanie do wywołania metody, konieczne jest wybranie jednej, aby zapewnić deskryptor metody run-time dispatch. Język programowania Java używa reguły, że wybierana jest najbardziej specyficzna metoda .

A char[] is-an Object, ale nie wszystkie Object is-a char[]. Dlatego char[] jest bardziej specyficznym niż Object i jak określa język Java, w tym przypadku wybiera się przeciążenie String.valueOf(char[]).

String.valueOf(char[]) oczekuje, że tablica będzie nie-null, a ponieważ null jest podana w tym przypadku, rzuca NullPointerException.

Łatwe "naprawić" jest rzut null jawnie do Object w następujący sposób:

System.out.println(String.valueOf((Object) null));
// prints "null"

Podobne pytania


Morał z historii

Jest kilka ważnych:

  • Effective Java 2nd Edition, poz. 41: używaj przeciążania rozsądnie
    • Just because możesz przeciążać, nie oznacza to, że powinieneś za każdym razem]} Mogą powodować zamieszanie (zwłaszcza jeśli metody robią szalenie różne rzeczy)]}
  • używając dobrego IDE, możesz sprawdzić, które przeciążenie jest wybrane podczas kompilacji
    • Z Eclipse, możesz najechać myszką na powyższe wyrażenie i zobaczyć, że rzeczywiście, valueOf(char[]) przeciążenie jest zaznaczone!
  • czasami chcesz wyraźnie rzucić null (przykłady do naśladowania)

Zobacz również


On casting null

Istnieją co najmniej dwie sytuacje, w których konieczne jest jednoznaczne rzucenie null na określony typ odniesienia:{[27]]}

    [29]} aby wybrać przeciążenie (jak podano w powyższym przykładzie)
  • aby dać null jako pojedynczy argument parametru vararg

Prosty przykład ostatnia jest następująca:

static void vararg(Object... os) {
    System.out.println(os.length);
}

Wtedy możemy mieć:

vararg(null, null, null); // prints "3"
vararg(null, null);       // prints "2"
vararg(null);             // throws NullPointerException!

vararg((Object) null);    // prints "1"

Zobacz też

Podobne pytania

 183
Author: polygenelubricants,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:27

Problem polega na tym, że dzwonisz String.valueOf(char[]) i nie String.valueOf(Object).

Powodem tego jest to, że Java zawsze wybierze najbardziej konkretną wersję przeciążonej metody, która będzie działać z podanymi parametrami. {[3] } jest poprawną wartością dla parametru Object, ale jest również poprawną wartością dla parametru char[].

Aby Java używała wersji Object, należy przekazać null poprzez zmienną lub określić jawny rzut do obiektu:

Object o = null;
System.out.println("String.valueOf(null) = " + String.valueOf(o));
// or
System.out.println("String.valueOf(null) = " + String.valueOf((Object) null));
 13
Author: Joachim Sauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-28 11:52:53

Bug, numerowany 4867608 został złożony w ten sposób w 2003 roku, który został rozwiązany jako "nie naprawi" z tym wyjaśnieniem.

Nie możemy tego zmienić ze względu na ograniczenia kompatybilności. Zauważ, że jest to public static String valueOf (char data[]) metoda, która kończy się wywoływane i nie wspomina o zastąpieniu "null" dla argumenty zerowe.

@###.### 2003-05-23

 5
Author: cbare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-11 05:18:16