Java在泛型方法中使用泛型数组

时间:2018-05-04 07:43:31

标签: java generics

我是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中的数组是支持协变而不是逆变。

因此,上面的代码在编译和运行时都有效。我的理解肯定有些不对劲。但我找不到。谁能帮我?谢谢!

1 个答案:

答案 0 :(得分:1)

T代表具体类型,不能代替Object。它带有实际类型。因此,当您将Integer[]传递给该方法时,它将返回Integer[]并且它正常工作 - 编译器知道类型。

使用第二种方法,当Object[]获得所期望的行为时,您可以将Integer[]传递给Object[],但不能反过来,而且会出现编译错误。< / p>

工作示例:

    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[]
    }