我是 Java 新手。据我所知,It's basically the way that generics are implemented in Java via compiler trickery 。
public Object doSomething(Object obj) {....}
public <T> T doSomething(T t) {....}
根据类型删除,上面两种方法在运行时是一样的。唯一不同的是我们使用这个方法的方式,当我们使用泛型方法时,编译器会自动添加类型转换。
Foo newFoo = (Foo) my.doSomething(foo);
同样,当我们在方法中使用泛型数组时,如下所示:
public void <T> T[] f(T[] args){
return args;
}
public void <T> Object[] f(Object[] args){
return args;
}
由于类型删除,我认为上述两种方法在运行时是相同的。
Integer[] a = {1, 2};
Integer[] b = test.f(a);
当我使用这个方法时,我认为通用方法会抛出CaseException。
当我们将 a
传递给 test.f(a)
时,JVM 将 Integer[]
转换为 Object[]
。
当我们从该方法获取结果时,JVM 也会将 Object[]
转换为 Integer[]
,并且此转换将抛出 CaseException。因为java中的数组支持协变,但不支持逆变。
因此,上述代码在编译和运行时都有效。我的理解一定有问题。但我查不出来。谁能帮我?谢谢!
最佳答案
T
代表具体类型,它不能替代 Object
。它本身带有实际类型。因此,当您将 Integer[]
传递给该方法时,它会返回 Integer[]
并且它可以正常工作 - 编译器知道类型。
使用第二种方法,当您拥有 Object[]
时,您会得到您期望的行为 - 您可以将 Integer[]
传递给 Object[]
> 但反之亦然,你会得到编译器错误。
工作示例:
public static <T> T[] f1(T[] args){
return args; //That one works because we return T[]
}
public static <T> T[] f2(Object[] args){
return (T[])args; //That one also works because we return T[]
}
下一个不起作用,因为我们返回 Object[],它可能是 T 类型,但也可能是另一种类型 - 它无法编译
public static Object[] f2(Object[] args){
return args; //Object[] is not T[]
}
关于Java在泛型方法中使用泛型数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50169738/