我偶然发现了这个问题,它引起了我的兴趣。接受的答案是完全正确的,但我认为我确实在 JVM 字节码级别提供了我的发现来解释为什么 OP 遇到ClassCastException
.
我的代码与 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);
}
对应的字节码是:
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
请注意,checkcast
字节码指令发生在 main 方法中,而不是convertInstanceOfObject
andconvertInstanceOfObject
方法没有任何可以 throw 的指令ClassCastException
。因为 main 方法没有捕获,ClassCastException
因此当您执行 main 方法时,您将得到 aClassCastException
而不是 print 的期望null
。
现在我将代码修改为接受的答案:
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);
}
对应的字节码为:
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
请注意,方法中有一条invokevirtual
指令convertInstanceOfObject
调用Class.cast()
throws的方法,该方法ClassCastException
将被catch(ClassCastException e)
bock 捕获并返回null
;因此,“null”会毫无例外地打印到控制台。