[JAVA] Autoboxing que j'ai appris en tant que NullPointerException dans la comparaison courte

Utilisez ʻequals` lors de la comparaison de valeurs dans une classe wrapper

On le dit souvent dans la comparaison de String. Si vous utilisez == en comparaison Pour les ** types de référence tels que les wrappers, comparez les ** référencés et pour les ** types primitifs, comparez la valeur **.

String hoge = "hoge";
String fuga = "hogehoge";
fuga = fuga.substring(4); // << "hoge"devenir

//Puisque la destination de référence est comparée, elle devient "fausse"
boolean isEqual1 = hoge == fuga;

//Puisque les valeurs sont comparées, cela devient «vrai».
boolean isEqual2 = hoge.equals(fuga);
System.out.print(isEqual2);

Même si vous utilisez == pour comparer Shorts, la plage de "-128 à 127" comparera les valeurs.

J'ai comparé par inadvertance Short (emballage court) avec ==, mais je ne l'ai pas remarqué à mi-chemin, j'ai remarqué que la valeur atteignait environ 200. Je ne savais pas ... mais vous devriez utiliser ʻequals`.

Boolean isEquala = null;
// 「-128~Puisqu'il est hors de la plage de «127», il devient «faux».
Short a1 = -129;
Short a2 = -129;
isEqual = a1 == a2;
// 「-128~Puisqu'il est dans la plage de «127», il devient «vrai».
Short b1 = -128;
Short b2 = -128;
isEqual = b1 == b2;
// 「-128~Puisqu'il est dans la plage de «127», il devient «vrai».
Short c1 = 127;
Short c2 = 127;
isEqual = c1 == c2;
// 「-128~Puisqu'il est hors de la plage de «127», il devient «faux».
Short d1 = 128;
Short d2 = 128;
isEqual = d1 == d2;

Probablement pour la même raison que Integer.

Parce que "Integer.valueOf ()" est utilisé à la place de "new Integer ()" de int à Integer. Ceci renvoie (actuellement) des entiers mis en cache dans la plage -128-127, donc ils sont la même instance dans cette plage. Par conséquent, même s'ils sont comparés à ==, ils sont égaux. Mémo de type Java (Mémo de type Java de Hishidama)

NullPointerException même si == est utilisé dans la comparaison courte

J'ai été surpris ... je ne comprends pas

Short a = null;
Boolean isOne = null;
//NullPointerException comme prévu
isOne = a.equals(1);
//Devenez "vrai" comme vous pouvez l'imaginer
isOne = a == null;
//Étonnamment, j'obtiens une NullPointerException!
isOne = a == 1;
//Ce sera "false" au lieu d'une NullPointerException
isOne = a == new Short("1");
//Ce sera également "faux"
Integer i = 1;
isOne = a == new Short(i.shortValue());

Il existe une transformation de boxe qui transforme automatiquement les types primitifs et les classes wrapper

Il semble que cela soit devenu possible à partir du JDK1.5, et je ne savais pas qu'il y avait un tel nom.

//Affectation ordinaire à la classe wrapper
Short a1 = new Short("1000");
//Autoboxing: conversion automatique des types primitifs en classes wrapper
Short a2 = 1000; //Lorsque je compile le fichier de classe, cela ressemble à ceci>> Short a2 = Short.valueOf((short)1000);

//Affectation ordinaire au type primitif
short b1 = a1.shortValue();
//Unboxing: conversion automatique des classes wrapper en types primitifs
short b2 = a2; //Lorsque je compile le fichier de classe, cela ressemble à ceci>> short b2 = a2.shortValue();

J'ai essayé de compiler à rebours l'endroit où == était utilisé dans la comparaison courte pour voir s'il était converti en boîte

Il semble que vous puissiez dire s'il est converti en boîte par compilation inverse, J'ai donc essayé la compilation inverse.

Lorsque je reverse-compile la version compilée, elle est simplement remplacée par la méthode de conversion ... Mémo de type Java (Mémo de type Java de Hishidama)

isOne = a.equals(1);
//↑ Si vous compilez ceci et que vous le compilez à l'envers, ce sera comme ceci ↓
isOne = Boolean.valueOf(a.equals(Integer.valueOf(1)));

isOne = a == null;
//↑ Si vous compilez ceci et que vous le compilez à l'envers, ce sera comme ceci ↓
isOne = Boolean.valueOf(a == null);

isOne = a == 1;
//↑ Si vous compilez ceci et que vous le compilez à l'envers, ce sera comme ceci ↓
isOne = Boolean.valueOf(a.shortValue() == 1);

isOne = a == new Short("1");
//↑ Si vous compilez ceci et que vous le compilez à l'envers, ce sera comme ceci ↓
isOne = Boolean.valueOf(a == new Short("1"));

Integer i = 1;
isOne = a == new Short(i.shortValue());
//↑ Si vous compilez ceci et que vous le compilez à l'envers, ce sera comme ceci ↓
Integer i = Integer.valueOf(1);
isOne = Boolean.valueOf(a == new Short(i.shortValue()));

La comparaison de Short avec un type primitif par == entraînera une NullPointerException car shortValue () est exécuté!

a == 1;
//↑ devient comme ça ↓
Boolean.valueOf(a.shortValue() == 1);

Je comprends la raison de NullPointerException, mais pourquoi est-ce shortValue () seulement quand c'est un nombre littéral? ʻA == new Short ("1"); ne sera pas Boolean.valueOf (a.shortValue () == new Short (i.shortValue ()));`?

@Swordone m'a posé une telle question.

Si vous comparez la classe wrapper (type de référence) avec le type primitif, l'autoboxing sera effectué, donc Si la cible de comparaison est un type de référence, «.shortValue ()» n'est pas exécuté et NullPointerException ne se produit pas.

//Par exemple, cela est dû au fait que la cible de comparaison est un type primitif
boolean isOne = a == (short) 1;
//La boxe automatique est effectuée(↓ Résultat de la compilation inversée)
boolean isOne = a.shortValue() == 1;


Recommended Posts

Autoboxing que j'ai appris en tant que NullPointerException dans la comparaison courte
Méthodes que j'ai trouvées utiles dans Ruby
Ce que j'ai appris en Java (partie 2) Que sont les variables?
Résumé de ce que j'ai appris dans Spring Batch