假设我想通过默认构造函数
创建一个长度为5的数组public class A <E extends Comparable<? super E>> implements B<E>
{
private E[] myArray;
public A()
{
myArray = (E[]) new Object[5];
}
}
这是正确的做法吗?我很困惑,我是否必须这样做 在[]之前陈述“可比较”。所以
private Comparable[] myArray;
答案 0 :(得分:4)
不。它将在运行时抛出ClassCastException
让我们看看原因。因为<E extends Comparable<? super E>>
,一旦编译器删除了所有泛型类型,E
将在整个类中被Comparable
替换。
因此,在构造函数中,这是主要在运行时发生的事情:
myArray = new Comparable[5];
哪个是错的,因此也是例外。
它适用于class A <E> implements B<E>
所以解决方案是:
class A <E extends Comparable<? super E>> implements B<E>{
Comparable[] array;
public A(){
array = new Comparable[5];
}
@SuppressWarnings("unchecked")
E get(int x)
{
return (E) array[x];
}
void add(E b){
//for now
array[0] = b;
}
答案 1 :(得分:2)
您发布的代码的问题是E[]
的删除是Comparable[]
(因为E
的上限是Comparable
),所以强制转换一个对象,实际类型为Object[]
到Comparable[]
将失败。
您可以简单地将其更改为以下内容,它不会抛出异常:
public class A <E extends Comparable<? super E>> implements B<E>
{
private E[] myArray;
public A()
{
myArray = (E[]) new Comparable[5];
}
}
但是,这里有更多细微之处:myArray
并非真正属于E[]
类型。在课堂上,E[]
被删除为Comparable[]
,所以没关系。但是你必须确保永远不要将myArray
暴露给课外。由于它是私有的,你只需要确保没有方法返回它或什么。
这样做的好处是保持myArray
类型E[]
,而不是Jatin使用Comparable[]
的答案,就是每次你得到某些东西时都不需要施放出来,所以代码更好。
答案 2 :(得分:1)
正如@Jatin指出的那样,如果你将Object
强制转换为Comparable
,你会得到一个运行时异常,因为它是Comparable
的超级,因此无法转换为子类型。
我建议您尽可能使用ArrayList
:
e.g。
public class A <E extends Comparable<? super E>> implements B<E> {
private List<E> myArray;
public A() {
myArray = new ArrayList<E>();
}
}