Eu me deparo com essa pergunta e ela me interessou. A resposta aceita está completamente correta, mas pensei em fornecer minhas descobertas no nível de código de bytes da JVM para explicar por que o OP encontra o ClassCastException
.
Eu tenho o código que é praticamente o mesmo que o código do 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);
}
e o código de bytes correspondente é:
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
Observe que a checkcast
instrução do código de bytes ocorre no método principal, e não o método convertInstanceOfObject
e convertInstanceOfObject
não possui nenhuma instrução que possa ser lançada ClassCastException
. Como o método principal não captura, ClassCastException
portanto, quando você executa o método principal, você obtém uma ClassCastException
e não a expectativa de impressão null
.
Agora eu modifico o código para a resposta aceita:
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);
}
O código de bytes correspondente é:
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
Observe que existe uma invokevirtual
instrução no convertInstanceOfObject
método que chama o Class.cast()
método que lança ClassCastException
que será capturado pela catch(ClassCastException e)
bock e retornará null
; portanto, "null" é impresso no console sem nenhuma exceção.
null
? e, por que você não retorna umObject
? O apagamento de Java de qualquer maneira traduz seu genérico em umObject
, então por que você não escreve diretamentepublic static Object convertInstanceOfObject
?