Pourquoi le suivant fonctionne-t-il? Je m’attendrais à ce qu’une NullPointerException
soit lancée.
Ssortingng s = null; s = s + "hello"; System.out.println(s); // prints "nullhello"
Le JLS 5, Section 15.18.1.1 JLS 8 § 15.18.1 “Opérateur de concaténation de chaînes +” , menant au JLS 8, § 5.1.11 “Conversion de chaînes” , exige que cette opération aboutisse sans échec:
… Maintenant, seules les valeurs de référence doivent être sockets en compte. Si la référence est null, elle est convertie en la chaîne “null” (quatre caractères ASCII n, u, l, l). Sinon, la conversion est effectuée comme par une invocation de la méthode toSsortingng de l’object référencé sans arguments; mais si le résultat de l’invocation de la méthode toSsortingng est null, la chaîne “null” est utilisée à la place.
Regardons le bytecode! Le compilateur prend votre code:
Ssortingng s = null; s = s + "hello"; System.out.println(s); // prints "nullhello"
et le comstack en bytecode comme si vous aviez écrit ceci:
Ssortingng s = null; s = new SsortingngBuilder(Ssortingng.valueOf(s)).append("hello").toSsortingng(); System.out.println(s); // prints "nullhello"
(Vous pouvez le faire vous-même en utilisant javap -c
)
Les méthodes append de SsortingngBuilder
gèrent toutes les SsortingngBuilder
nulles. Dans ce cas, parce que null
est le premier argument, Ssortingng.valueOf()
est invoqué à la place, car SsortingngBuilder ne possède pas de constructeur prenant un type de référence arbitraire.
Si vous aviez fait s = "hello" + s
place, le code équivalent serait:
s = new SsortingngBuilder("hello").append(s).toSsortingng();
où, dans ce cas, la méthode append prend la valeur null et la délègue ensuite à Ssortingng.valueOf()
.
Remarque: La concaténation de chaînes est en fait l’un des rares endroits où le compilateur peut décider des optimisations à effectuer. En tant que tel, le code “équivalent exact” peut différer d’un compilateur à l’autre. Cette optimisation est autorisée par JLS, Section 15.18.1.2 :
Pour augmenter les performances de la concaténation de chaînes répétée, un compilateur Java peut utiliser la classe SsortingngBuffer ou une technique similaire pour réduire le nombre d’objects Ssortingng intermédiaires créés par l’évaluation d’une expression.
Le compilateur que j’ai utilisé pour déterminer le “code équivalent” ci-dessus était le compilateur d’Eclipse, ecj .
Voir les sections 5.4 et 15.18 de la spécification du langage Java:
La conversion de chaîne s’applique uniquement aux opérandes de l’opérateur binary + lorsqu’un des arguments est une chaîne. Dans ce cas particulier, l’autre argument du + est converti en un Ssortingng, et un nouveau Ssortingng qui est la concaténation des deux chaînes est le résultat du +. La conversion de chaîne est spécifiée en détail dans la description de l’opérateur de concaténation de chaîne +.
et
Si une seule expression d’opérande est de type Ssortingng, la conversion de chaîne est effectuée sur l’autre opérande pour produire une chaîne au moment de l’exécution. Le résultat est une référence à un object Ssortingng (nouvellement créé, sauf si l’expression est une expression constante de compilation (§15.28)) qui est la concaténation des deux chaînes d’opérande. Les caractères de l’opérande gauche précèdent les caractères de l’opérande droit dans la chaîne nouvellement créée. Si un opérande de type Ssortingng est nul, la chaîne “null” est utilisée à la place de cet opérande.
La deuxième ligne est transformée en le code suivant:
s = (new SsortingngBuilder()).append((Ssortingng)null).append("hello").toSsortingng();
Les méthodes append peuvent gérer null
arguments null
.
Vous n’utilisez pas le “null” et vous ne recevez donc pas l’exception. Si vous voulez le NullPointer, faites simplement
Ssortingng s = null; s = s.toSsortingng() + "hello";
Et je pense que ce que vous voulez faire est:
Ssortingng s = ""; s = s + "hello";
C’est le comportement spécifié dans la méthode Ssortingng.valueOf(Object)
API Java. Lorsque vous faites de la concaténation, valueOf
est utilisé pour obtenir la représentation Ssortingng
. Il y a un cas particulier si l’object est null
, auquel cas la chaîne "null"
est utilisée.
public static Ssortingng valueOf(Object obj)
Renvoie la représentation sous forme de chaîne de l’argument Object.
Paramètres: obj – un object.
Résultats:
si l’argument est nul, alors une chaîne égale à “null”; sinon, la valeur de obj.toSsortingng () est renvoyée.