Je suis tombé sur cette question et elle a suscité mon intérêt. La réponse acceptée est tout à fait correcte, mais j'ai pensé que je devais fournir mes conclusions au niveau du code d'octet de la JVM pour expliquer pourquoi le PO a rencontré le problème suivant ClassCastException
.
J'ai le code qui est à peu près le même que celui de l'OP :
public static <T> T convertInstanceOfObject(Object o) {
try {
return (T) o;
} catch (ClassCastException e) {
return null;
}
}
public static void main(String[] args) {
String k = convertInstanceOfObject(345435.34);
System.out.println(k);
}
et le code d'octet correspondant est :
public static <T> T convertInstanceOfObject(java.lang.Object);
Code:
0: aload_0
1: areturn
2: astore_1
3: aconst_null
4: areturn
Exception table:
from to target type
0 1 2 Class java/lang/ClassCastException
public static void main(java.lang.String[]);
Code:
0: ldc2_w #3 // double 345435.34d
3: invokestatic #5 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
6: invokestatic #6 // Method convertInstanceOfObject:(Ljava/lang/Object;)Ljava/lang/Object;
9: checkcast #7 // class java/lang/String
12: astore_1
13: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
16: aload_1
17: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
20: return
Remarquez que checkcast
l'instruction de code d'octet se produit dans la méthode principale et non dans la méthode convertInstanceOfObject
y convertInstanceOfObject
n'a pas d'instruction qui puisse lancer ClassCastException
. Parce que la méthode principale n'attrape pas le ClassCastException
Ainsi, lorsque vous exécutez la méthode principale, vous obtiendrez un message de type ClassCastException
et non l'attente de l'impression null
.
Maintenant je modifie le code pour la réponse acceptée :
public static <T> T convertInstanceOfObject(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch (ClassCastException e) {
return null;
}
}
public static void main(String[] args) {
String k = convertInstanceOfObject(345435.34, String.class);
System.out.println(k);
}
Le code d'octet correspondant est :
public static <T> T convertInstanceOfObject(java.lang.Object, java.lang.Class<T>);
Code:
0: aload_1
1: aload_0
2: invokevirtual #2 // Method java/lang/Class.cast:(Ljava/lang/Object;)Ljava/lang/Object;
5: areturn
6: astore_2
7: aconst_null
8: areturn
Exception table:
from to target type
0 5 6 Class java/lang/ClassCastException
public static void main(java.lang.String[]);
Code:
0: ldc2_w #4 // double 345435.34d
3: invokestatic #6 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
6: ldc #7 // class java/lang/String
8: invokestatic #8 // Method convertInstanceOfObject:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
11: checkcast #7 // class java/lang/String
14: astore_1
15: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;
18: aload_1
19: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
22: return
Remarquez qu'il y a un invokevirtual
l'instruction dans le convertInstanceOfObject
qui appelle Class.cast()
qui lance la méthode ClassCastException
qui sera attrapé par le catch(ClassCastException e)
bock et retour null
; par conséquent, "null" est imprimé sur la console sans aucune exception.