[英]Cast Object to Generic Type for returning
Is there a way to cast an object to return value of a method?有没有办法将对象强制转换为方法的返回值? I tried this way but it gave a compile time exception in "instanceof" part:
我试过这种方式,但它在“instanceof”部分给出了一个编译时异常:
public static <T> T convertInstanceOfObject(Object o) {
if (o instanceof T) {
return (T) o;
} else {
return null;
}
}
I also tried this one but it gave a runtime exception, ClassCastException:我也试过这个,但它给出了一个运行时异常,ClassCastException:
public static <T> T convertInstanceOfObject(Object o) {
try {
T rv = (T)o;
return rv;
} catch(java.lang.ClassCastException e) {
return null;
}
}
Is there a possible way of doing this easily:有没有办法轻松做到这一点:
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"
EDIT: I wrote a working copy of the correct answer:编辑:我写了一份正确答案的工作副本:
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);
}
You have to use a Class
instance because of the generic type erasure during compilation.由于编译期间的泛型类型擦除,您必须使用
Class
实例。
public static <T> T convertInstanceOfObject(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch(ClassCastException e) {
return null;
}
}
The declaration of that method is:该方法的声明是:
public T cast(Object o)
This can also be used for array types.这也可用于数组类型。 It would look like this:
它看起来像这样:
final Class<int[]> intArrayType = int[].class;
final Object someObject = new int[]{1,2,3};
final int[] instance = convertInstanceOfObject(someObject, intArrayType);
Note that when someObject
is passed to convertToInstanceOfObject
it has the compile time type Object
.请注意,当
someObject
传递给convertToInstanceOfObject
它具有编译时类型Object
。
I stumble upon this question and it grabbed my interest.我偶然发现了这个问题,它引起了我的兴趣。 The accepted answer is completely correct, but I thought I do provide my findings at JVM byte code level to explain why the OP encounter the
ClassCastException
.接受的答案是完全正确的,但我认为我确实在 JVM 字节码级别提供了我的发现来解释为什么 OP 遇到
ClassCastException
。
I have the code which is pretty much the same as OP's code:我的代码与 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);
}
and the corresponding byte code is:对应的字节码为:
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
Notice that checkcast
byte code instruction happens in the main method not the convertInstanceOfObject
and convertInstanceOfObject
method does not have any instruction that can throw ClassCastException
.请注意,
checkcast
字节码指令发生在 main 方法而不是convertInstanceOfObject
并且convertInstanceOfObject
方法没有任何可以抛出ClassCastException
指令。 Because the main method does not catch the ClassCastException
hence when you execute the main method you will get a ClassCastException
and not the expectation of printing null
.因为 main 方法没有捕获
ClassCastException
因此当你执行 main 方法时你会得到一个ClassCastException
而不是打印null
的期望。
Now I modify the code to the accepted answer:现在我将代码修改为接受的答案:
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);
}
The corresponding byte code is:对应的字节码为:
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
Notice that there is an invokevirtual
instruction in the convertInstanceOfObject
method that calls Class.cast()
method which throws ClassCastException
which will be catch by the catch(ClassCastException e)
bock and return null
;注意,有一个
invokevirtual
在指令convertInstanceOfObject
调用方法Class.cast()
方法,其抛出ClassCastException
,这将是由抓catch(ClassCastException e)
博克和返回null
; hence, "null" is printed to console without any exception.因此,“null”毫无例外地打印到控制台。
If you do not want to depend on throwing exception (which you probably should not) you can try this:如果你不想依赖抛出异常(你可能不应该这样做),你可以试试这个:
public static <T> T cast(Object o, Class<T> clazz) {
return clazz.isInstance(o) ? clazz.cast(o) : null;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.