Ljava.lang.Object; 无法转换为[Ljava.lang.Integer

我写了一个generics类,下面是类的构造函数。 我想做这样的事情,就像写在线一样

elements = (E[])new Object[size] 

因为我不知道运行时的generics类型因此会抛出exception。

 public class Stack implements IStack { protected E[] elements = null; protected int top = -1; protected int size= 0; private static final int DEFAULT_CAPACITY = 10; public Stack(){ this(DEFAULT_CAPACITY); } public Stack(int size){ if(size <0){ throw new IllegalArgumentException("Initial capacity cannot be negative or zero"); } ArrayList ar = new ArrayList(); elements = (E[])new Object[size]; } } 

有什么方法可以解决这些问题吗? E的声明是

 protected E[] elements = null; 

这就是我试图打电话的方式

 Random ran = new Random(); Stack st = new Stack(); st.push(ran.nextInt(100)); 

更新伙计们,感谢您的帮助。 我正在搞乱generics,所以问题正在形成。 以下是创建问题的所有代码 –

 public class StackMain { public static void main(String[] args) { MinMaxStack minMaxStack = new MinMaxStack(); Random ran = new Random(); for (int k = 0; k < 10; k++) { minMaxStack.push(ran.nextInt(100)); } System.out.println(minMaxStack); } } public class MinMaxStack extends Stack implements IMinMaxStack{ private int min; private int max; /* * Approach 1: * For push method we can push and update the minimum/maximum value * For pop method we will be traversing whole stack to find out the new minimum/maximum * */ @Override public void push(Integer element){ if(isEmpty()){ this.min = element; this.max = element; elements[top+1] = element; size++; }else{ if(element  max){ max = element; } elements[top+1] = element; size++; } } } public class Stack implements IStack { protected E[] elements = null; protected int top = -1; protected int size= 0; private static final int DEFAULT_CAPACITY = 10; public Stack(){ this(DEFAULT_CAPACITY); } public Stack(int size){ if(size <0){ throw new IllegalArgumentException("Initial capacity cannot be negative or zero"); } elements = (E[])new Object[size]; } public void push(E element) { ensureCapacity(); elements[top+1] = element; size++; } } public interface IStack { public void push(E element ); } public interface IMinMaxStack extends IStack { public int min(); public int max(); } 

更新2 :看起来,除了传递下面的答案中提到的类类型,我们无法做到这一点。

这是重现exception所需的最小代码。

 class Stack { protected E[] elements = (E[])new Object[1]; } class IntStack extends Stack { void push(Integer i) { // subtly accessing elements as Integer[] which it's not elements[0] = i; } } 

Javagenerics是使用类型擦除实现的,因此在编译之后,此代码转换为如下所示:

 class Stack { protected Object[] elements = new Object[1]; } class IntStack extends Stack { void push(Integer i) { // throws ClassCastException ((Integer[])elements)[0] = i; } } 

显然, new Object[]不是Integer[] 。 注意演员如何移动到你没有明确表达的地方。 这就是为什么(E[])new Object[size]未经检查的强制转换并显示警告的原因。

相反,您应该使用Object[]并仅在需要将元素返回到外部世界时执行未经检查的强制转换。

 class Stack { private Object[] elements; private int size; Stack(int len) { elements = new Object[len]; } void push(E e) { elements[size] = e; size++; } E pop() { @SuppressWarnings("unchecked"); E e = (E)elements[size - 1]; size--; return e; } } 

基本上,当你做(E[])new Object[size] ,这是一个谎言。 对象的实际运行时类是Object[] ,它不是E[]的子类型,无论E是什么(除非EObject )。 因此,演员在理论上是不正确的。 但是,这不会立即产生任何问题,因为在Stack类中, E被擦除到其上限,在本例中为Object 。 所以在Stack类中,我们可以使用elements作为E[] ,并将E放入并从中获取E ,没有问题。

只有当elements类型为E[]的(不正确的)事实被“暴露”到类的外部(在E的擦除范围之外)到某个范围内,其中有人具有E的具体类型参数时,才会出现问题。 。 这通常发生在有人无意中使elements公开,或实现一个将其返回到外部的方法时

 E[] getElements() { return elements; } 

然后在类的外部,有人有一个Stack ,并调用此方法,并期望SomeSpecificType[] ,这不是它得到的。

但是,您的Stack类没有这样的方法。 那你怎么“暴露” elements ? 答案是elements protected ,因此“暴露”到子类。 在这种情况下,子类MinMaxStack使用E的特定类型扩展Stack ,因此,它将elements “视为”特定类型的数组,而不是。

我相信通常的方法是将Class传递给构造函数,并使用Array.newInstance(Class, int...)类的

 public Stack(Class cls, int size){ if(size <0){ throw new IllegalArgumentException("Initial capacity cannot be " + "negative or zero"); } elements = (E[]) Array.newInstance(cls, size); } 

编辑

从您的更新, 不要使用原始类型 。 使用Java 7及更高版本,您可以使用菱形运算符<>

 Stack st = new Stack<>(); st.push(ran.nextInt(100)); 

对于早期版本,您可以指定generics类型

 Stack st = new Stack(); st.push(ran.nextInt(100)); 

现在很清楚了。 您正在尝试创建没有generics类型的Stack 。 考虑Stack st = new Stack<>(); 代替。

以下是修复它的方法,你不应该做(T[]) new Object[DEFAULT_CAPACITY]; 相反,抽象应该存在例如(T[]) new Comparable[DEFAULT_CAPACITY];

 public class ArrayStack> implements Stack { private final int DEFAULT_CAPACITY = 50; private int top; private T[] elements; @SuppressWarnings("unchecked") public ArrayStack() { this.elements = (T[]) new Comparable[DEFAULT_CAPACITY]; this.top = 0; } }