java - 为什么强制转换为泛型才生效?

标签 java generics

关于 Java revisited ,代码摘录如下:

class Holder<T>{
  private T[] contents;
  private int index = 0;
  public Holder(int size){
    //contents = new T[size]; //compiler error - generic array creation
    contents = (T[]) new Object[size]; //workaround - casting Object[] to generic Type
  }...}

它用于创建泛型数组,但根据类型删除(我在 java 在线教程上查过),T 在类编译时结束为 Object,因此强制转换(T[]) 将结束于 (Object[]),这似乎与不强制转换没有区别

那么那个casting的作用是什么或者casting有什么特殊的意义呢?任何提示都很感激。

最佳答案

强制转换需要告诉编译器我们这边的赋值是好的。否则它会告诉你编译器错误。

由于类型删除,类型参数 T在编译时被替换为它的删除。 无界类型参数的删除是 Object ,而有界类型参数的删除是表示上限的类型。所以,如果你在类中的类型参数有一个上限 - Holder<T extends Number> , 然后删除 T将是 Number .这意味着,T将替换为 Number由编译器。

所以,在这种情况下,因为 T在无界中,它的删除是Object .因此,它被替换为 Object由编译器。

即使转换消除了编译器错误,编译器仍会向您显示 Unchecked Cast 警告。因为,转换不是类型安全的,并且会在运行时失败并返回 ClassCastException。如果您使用 String 实例化通用类型类型参数。

试试这个:

Holder<String> stringHolder = new Holder<>(5);
String[] contents = stringHolder.getContents();  // ClassCastException

创建通用数组的更安全方法是使用 Array.newInstance方法。你需要通过 Class<T>将参数传递给构造函数,然后使用以下代码:

public Holder(int size, Class<T> clazz){
    contents = (T[]) Array.newInstance(clazz, size);
}

在这里您还会看到 Unchecked Cast警告。但那是无害的。

更安全的方法是根本不创建一个组件类型是类型参数的数组。您可以使用 ArrayList<T>相反。


引用:

关于java - 为什么强制转换为泛型才生效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18328546/

相关文章:

java - 功能接口(interface)接受流还是可选?

java - java中这两个对象初始化有什么区别?

java - 此处不允许出现“Void”类型错误

java - 从 Activity B 返回到 Activity A 的 fragment

java - 有没有办法使用 Javax.mail 检查电子邮件是否存在?

java - 为什么 Java 不允许您从泛型类型变量继承?

c# - 泛型列表<List<T>>

javac错误: inconvertible types with generics?

java - 如何检查用户是否正在输入消息

java - Spring MVC : Correct Annotation of Controller Method for RESTful URI including ';'