On 重温Java http://javarevisited.blogspot.tw/2011/09/generics-java-example-tutorial.html,代码摘录如下:
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[])
,这似乎需要与不铸造没有区别.
那么这个铸件的作用是什么,或者铸件有什么特殊意义吗?任何提示都是值得感激的。
需要进行强制转换来告诉编译器我们这边的分配是正确的。否则它会显示编译器错误。
由于类型擦除,类型参数T
被编译时的擦除所取代。
无界类型参数的擦除是Object
,而有界类型参数的擦除是表示上限的类型。因此,如果类中的类型参数有上限 -Holder<T extends Number>
,然后擦除T
将Number
。这意味着,T
将被替换为Number
由编译器。
所以,在这种情况下,自从T
在无界中,它的擦除是Object
。所以,它被替换为Object
由编译器。
即使转换消除了编译器错误,编译器仍然会向您显示未检查转换的警告。因为,强制转换不是类型安全的,并且会在运行时失败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 通用常见问题解答 - Angelika Langer http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#Can%20I%20create%20an%20array%20whose%20component%20type%20is%20a%20type%20parameter?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)