Oui, en appelant getClass()
est devenu un "test" canonique pour les null
idiome ", comme getClass()
est censée être une opération intrinsèque peu coûteuse et, je suppose, HotSpot pourrait être capable de détecter ce modèle et de réduire l'opération à une opération intrinsèque. null
-si le résultat de l'opération getClass()
n'est pas utilisé.
Un autre exemple est la création d'une instance de classe interne avec une instance externe qui n'est pas this
:
public class ImplicitNullChecks {
class Inner {}
void createInner(ImplicitNullChecks obj) {
obj.new Inner();
}
void lambda(Object o) {
Supplier<String> s=o::toString;
}
}
se compile en
Compiled from "ImplicitNullChecks.java"
public class bytecodetests.ImplicitNullChecks {
public bytecodetests.ImplicitNullChecks();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
void createInner(bytecodetests.ImplicitNullChecks);
Code:
0: new #23 // class bytecodetests/ImplicitNullChecks$Inner
3: dup
4: aload_1
5: dup
6: invokevirtual #24 // Method java/lang/Object.getClass:()Ljava/lang/Class;
9: pop
10: invokespecial #25 // Method bytecodetests/ImplicitNullChecks$Inner."<init>":(Lbytecodetests/ImplicitNullChecks;)V
13: pop
14: return
void lambda(java.lang.Object);
Code:
0: aload_1
1: dup
2: invokevirtual #24 // Method java/lang/Object.getClass:()Ljava/lang/Class;
5: pop
6: invokedynamic #26, 0 // InvokeDynamic #0:get:(Ljava/lang/Object;)Ljava/util/function/Supplier;
11: astore_2
12: return
}
Voir aussi JDK-8073550 :
Dans notre bibliothèque de classes, il y a quelques endroits où l'on utilise l'astuce bizarre d'utiliser object.getClass() pour vérifier la nullité d'un objet. Bien que cela puisse sembler être une démarche intelligente, il s'agit en fait d'une confusion qui fait croire aux gens qu'il s'agit d'une pratique approuvée. pratique approuvée de vérification de la nullité.
Avec le JDK 7, nous avons Objects.requireNonNull qui fournit la vérification de la nullité et déclare l'intention correcte. correctement.
On peut se demander si cela ne devrait pas s'appliquer également aux contrôles intrinsèques des langages de programmation, étant donné que l'utilisation de Objects.requireNonNull
à cette fin créerait une dépendance à l'égard d'une classe extérieure à la classe java.lang
n'est pas visible dans le code source. Et dans ce cas précis, l'astuce n'est visible que pour ceux qui regardent le code byte. Mais il a été décidé de changer ce comportement avec Java 9.
C'est ainsi que jdk1.9.0b160
compile la même classe de test :
Compiled from "ImplicitNullChecks.java"
public class bytecodetests.ImplicitNullChecks {
public bytecodetests.ImplicitNullChecks();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
void createInner(bytecodetests.ImplicitNullChecks);
Code:
0: new #26 // class bytecodetests/ImplicitNullChecks$Inner
3: dup
4: aload_1
5: dup
6: invokestatic #27 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
9: pop
10: invokespecial #28 // Method bytecodetests/ImplicitNullChecks$Inner."<init>":(Lbytecodetests/ImplicitNullChecks;)V
13: pop
14: return
void lambda(java.lang.Object);
Code:
0: aload_1
1: dup
2: invokestatic #27 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
5: pop
6: invokedynamic #29, 0 // InvokeDynamic #0:get:(Ljava/lang/Object;)Ljava/util/function/Supplier;
11: astore_2
12: return
}