web-dev-qa-db-fra.com

Aucune exception lors de la conversion de type avec une valeur null en java

String x = (String) null;

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

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

Il imprime null. Mais la méthode .toString() devrait générer une exception de pointeur null.

182
Vicky

Vous pouvez transtyper null vers n'importe quel type de référence sans aucune exception.

La méthode println ne renvoie pas le pointeur null car elle vérifie d'abord si l'objet est null ou non. Si null, il affiche simplement la chaîne "null". Sinon, il appellera la méthode toString de cet objet.

Ajout de plus de détails: Les méthodes d'impression internes appellent la méthode String.valueOf(object) sur l'objet en entrée. Et dans la méthode valueOf, cette vérification permet d'éviter une exception de pointeur null:

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

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

265
Juned Ahsan

Vous pouvez convertir null en n’importe quel type de référence. Vous pouvez également appeler des méthodes qui gèrent un null en argument, par exemple. System.out.println(Object) le fait, mais vous ne pouvez pas référencer une valeur null et appeler une méthode dessus.

BTW Il existe une situation délicate dans laquelle il apparaît que vous pouvez appeler des méthodes statiques sur des valeurs null.

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

C'est par conception. Vous pouvez convertir null en n’importe quel type de référence. Sinon, vous ne pourrez pas l'affecter à des variables de référence.

32
André Stannek

La conversion de valeurs null est requise pour la construction suivante dans laquelle une méthode est surchargée et si null est transmis à ces méthodes surchargées, le compilateur ne sait pas comment lever l'ambiguïté. Par conséquent, nous devons typecast null dans les cas suivants:

class A {
  public void foo(Long l) {
    // do something with l
  }
  public void foo(String s) {
    // do something with s      
  }
}
new A().foo((String)null);
new A().foo((Long)null);

Sinon, vous ne pourriez pas appeler la méthode dont vous avez besoin.

14
Mewel

Println(Object) utilise String.valueOf()

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

Print(String) fait un contrôle nul.

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

Comme d'autres l'ont écrit, vous pouvez utiliser null pour tout. Normalement, vous n'en auriez pas besoin, vous pouvez écrire:

String nullString = null;

sans mettre le casting là-bas.

Mais il y a des occasions où de tels moulages ont un sens:

a) si vous voulez vous assurer qu'une méthode spécifique est appelée, comme:

void foo(String bar) {  ... }
void foo(Object bar) {  ... }

alors cela ferait une différence si vous tapez

foo((String) null) vs. foo(null)

b) si vous avez l'intention d'utiliser votre IDE pour générer du code; par exemple, j'écris typiquement des tests unitaires comme:

@Test(expected=NullPointerException.class)
public testCtorWithNullWhatever() {
    new MyClassUnderTest((Whatever) null);
}

Je fais du TDD; cela signifie que la classe "MyClassUnderTest" n'existe probablement pas encore. En écrivant ce code, je peux ensuite utiliser mon IDE pour générer d’abord la nouvelle classe; et pour générer ensuite un constructeur acceptant un argument "Peu importe" "immédiatement" - le IDE peut déduire de mon test que le constructeur doit prendre exactement un argument de type Quoi.

3
GhostCat

Beaucoup de réponses ici mentionnent déjà 

Vous pouvez convertir null en n'importe quel type de référence

et

Si l'argument est null, alors une chaîne égale à "null"

Je me suis demandé où cela était spécifié et j'ai consulté la spécification Java:

La référence null peut toujours être affectée ou transtypée en un type de référence quelconque (§5.2, §5.3, §5.5).

Si la référence est null, elle est convertie en chaîne "null" (quatre ASCII caractères n, u, l, l).

3
Arigion

Impression

Imprimer un objet. La chaîne 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 renvoyée.

Il renverra simplement une chaîne avec la valeur "null" lorsque l'objet est null.

2
Jeroen Vannevel

Ceci est très pratique lorsque vous utilisez une méthode qui serait autrement ambiguë. Par exemple: JDialog a des constructeurs avec les signatures suivantes:

JDialog(Frame, String, boolean, GraphicsConfiguration)
JDialog(Dialog, String, boolean, GraphicsConfiguration)

Je dois utiliser ce constructeur, car je veux définir GraphicsConfiguration, mais je n'ai pas de parent pour cette boîte de dialogue. Le premier argument doit donc être null. En utilisant

JDialog(null, String, boolean, Graphicsconfiguration) 

est ambigu, alors dans ce cas, je peux restreindre l'appel en convertissant null en l'un des types pris en charge:

JDialog((Frame) null, String, boolean, GraphicsConfiguration)
2
Marten Jacobs

Cette fonctionnalité de langue est pratique dans cette situation.

public String getName() {
  return (String) memberHashMap.get("Name");
}

Si memberHashMap.get ("Name") renvoie la valeur null, vous souhaiterez toujours que la méthode ci-dessus renvoie la valeur null sans lever d'exception. Quelle que soit la classe, null est null.

0
Changgull Song