java - sirve - Emitir objeto a tipo genérico para regresar
settitle java (3)
Debe usar una instancia de Class
debido a la eliminación de tipo genérico durante la compilación.
public static <T> T convertInstanceOfObject(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch(ClassCastException e) {
return null;
}
}
La declaración de ese método es:
public T cast(Object o)
Esto también se puede usar para tipos de matriz. Se vería así:
final Class<int[]> intArrayType = int[].class;
final Object someObject = new int[]{1,2,3};
final int[] instance = convertInstanceOfObject(someObject, intArrayType);
Tenga en cuenta que cuando someObject
se pasa a convertToInstanceOfObject
tiene el tiempo de compilación tipo Object
.
¿Hay alguna forma de lanzar un objeto para devolver el valor de un método? Intenté de esta manera pero me dio una excepción de tiempo de compilación en la parte "instancia de":
public static <T> T convertInstanceOfObject(Object o) {
if (o instanceof T) {
return (T) o;
} else {
return null;
}
}
También probé esta pero dio una excepción de tiempo de ejecución, ClassCastException:
public static <T> T convertInstanceOfObject(Object o) {
try {
T rv = (T)o;
return rv;
} catch(java.lang.ClassCastException e) {
return null;
}
}
¿Hay una manera posible de hacer esto fácilmente?
String s = convertInstanceOfObject("string");
System.out.println(s); // should print "string"
Integer i = convertInstanceOfObject(4);
System.out.println(i); // should print "4"
String k = convertInstanceOfObject(345435.34);
System.out.println(k); // should print "null"
EDITAR: Escribí una copia de trabajo de la respuesta correcta:
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 s = convertInstanceOfObject("string", String.class);
System.out.println(s);
Integer i = convertInstanceOfObject(4, Integer.class);
System.out.println(i);
String k = convertInstanceOfObject(345435.34, String.class);
System.out.println(k);
}
Me tropiezo con esta pregunta y me atrapó mi interés. La respuesta aceptada es completamente correcta, pero creo que proporciono mis hallazgos en el nivel de código de byte JVM para explicar por qué el OP encuentra ClassCastException
.
Tengo el código que es más o menos el mismo que el código de 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);
}
y el código de bytes correspondiente es:
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
Tenga en cuenta que la instrucción del código de bytes de checkcast
ocurre en el método principal, no el método convertInstanceOfObject
y el método convertInstanceOfObject
no tienen ninguna instrucción que pueda lanzar ClassCastException
. Debido a que el método principal no captura la ClassCastException
tanto, cuando ejecuta el método principal obtendrá una ClassCastException
y no la expectativa de impresión null
.
Ahora modifico el código a la respuesta aceptada:
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);
}
El código de bytes correspondiente es:
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 hay una instrucción invokevirtual
en el método convertInstanceOfObject
que llama al método Class.cast()
que arroja ClassCastException
que será capturada por catch(ClassCastException e)
bock y return null
; por lo tanto, "nulo" se imprime en la consola sin excepción.
Object obj;
return obj.getClass().cast( obj );
¡Puede usar esto directamente en lugar de especificar el nombre de clase del objeto!