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

标签 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中的数组支持协变,但不支持逆变。

因此,上述代码在编译和运行时都有效。我的理解一定有问题。但我查不出来。谁能帮我?谢谢!

最佳答案

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/

相关文章:

java - 函数名前的泛型 <T> 参数

java - 在使用 Spring JavaMail 发送电子邮件之前检索生成的 Message-ID

Java: vector 的大小(以字节为单位)

java - 从 Bouncy CaSTLe 中的文本创建 RSA 公钥时出现问题

java - 尝试在 Android Studio 中运行默认 map Activity 时出现模拟器错误

java - 为什么 Java 的 Class<T> 是泛型的?

java - 从 Java Google Cloud 创建启用 HTTP 的实例

Java:不同的泛型类型声明和实例

java - 删除如何处理 Java 中的覆盖场景?

java - 我应该使用问号类型参数还是抑制原始类型警告?