264 votes

Pas d'exception lors d'un casting de type avec un null en java

String x = (String) null;

Pourquoi n'y a-t-il pas d'exception dans cette déclaration ?

String x = null;
System.out.println(x);

Il imprime null . Mais .toString() doit lever une exception liée à un pointeur nul.

0 votes

De quelle exception parlez-vous, compilateur ?

368voto

Juned Ahsan Points 33217

Vous pouvez lancer null à tout type de référence sans obtenir d'exception.

Le site println ne lève pas le pointeur nul car elle vérifie d'abord si l'objet est nul ou non. S'il est nul, elle imprime simplement la chaîne de caractères "null" . Sinon, il appelle le toString de cet objet.

Ajout de détails supplémentaires : En interne, les méthodes d'impression appellent String.valueOf(object) sur l'objet d'entrée. Et dans valueOf cette vérification permet d'éviter les exceptions liées aux pointeurs nuls :

return (obj == null) ? "null" : obj.toString();

Pour le reste de votre confusion, l'appel de toute méthode sur un objet nul devrait lever une exception de pointeur nul, si ce n'est un cas spécial.

1 votes

@JunedAhsan Quels sont les cas particuliers qui feraient en sorte qu'il n'y ait pas de NPE ?

0 votes

@Trengot Vérifiez celui mentionné dans la réponse de Peter ci-dessous.

158voto

Peter Lawrey Points 229686

Vous pouvez lancer null à tout type de référence. Vous pouvez également appeler des méthodes qui gèrent un null comme argument, par exemple System.out.println(Object) mais vous ne pouvez pas faire référence à un null et appeler une méthode sur cette valeur.

BTW Il y a une situation délicate où il apparaît que vous pouvez appeler des méthodes statiques sur null valeurs.

Thread t = null;
t.yield(); // Calls static method Thread.yield() so this runs fine.

13 votes

Wow. Si on me le demandait, je serais sûr à 100 % que cela lèverait une exception. Un cas délicat en effet.

2 votes

@Magnilex : Absolument ! C'est une question piège typique de l'examen OCPJP.

3 votes

N'est-ce pas parce que le compilateur du bytecode l'"optimise" à t.yield() -> Thread.yeld() de toute façon ? De la même manière que final int i = 1; while (i == 1) est optimisé pour while(true)

41voto

André Stannek Points 3701

C'est à dessein. Vous pouvez lancer null à tout type de référence. Sinon, vous ne pourriez pas l'affecter à des variables de référence.

0 votes

Merci ! cette note concernant l'affectation de null aux variables de référence est vraiment utile !

8voto

rocketboy Points 5100

Println(Object) utilise String.valueOf()

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

Print(String) fait un contrôle de nullité.

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}

2voto

Jeroen Vannevel Points 18676

Imprimer :

Imprimer un objet. La chaîne de caractères produite par la méthode String.valueOf(Object) est traduite en octets

Valeur de :

si l'argument est null, alors une chaîne égale à "null" ; sinon, la valeur de obj.toString() est retournée.

Il retournera simplement une chaîne de caractères avec la valeur "null" lorsque l'objet est null .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X