- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
关于 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/
我是一名优秀的程序员,十分优秀!