![](/img/trans.png)
[英]Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
[英]Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer
我編寫了一個泛型類,下面是該類的構造函數。 我想做這樣的事情就像寫在線一樣
elements = (E[])new Object[size]
因為我不知道運行時的泛型類型因此會拋出異常。
public class Stack<E> implements IStack<E> {
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<Integer> ar = new ArrayList<Integer>();
elements = (E[])new Object[size];
}
}
有什么方法可以解決這些問題嗎? E的聲明是
protected E[] elements = null;
這就是我試圖打電話的方式
Random ran = new Random();
Stack<Integer> st = new Stack<Integer>();
st.push(ran.nextInt(100));
更新伙計們,感謝您的幫助。 我正在搞亂泛型,所以問題正在形成。 以下是創建問題的所有代碼 -
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<Integer> implements IMinMaxStack<Integer>{
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 < min){
min = element;
}
if(element > max){
max = element;
}
elements[top+1] = element;
size++;
}
}
}
public class Stack<E> implements IStack<E> {
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<E> {
public void push(E element );
}
public interface IMinMaxStack<E> extends IStack<E> {
public int min();
public int max();
}
更新2 :看起來,除了傳遞下面的答案中提到的類類型,我們無法做到這一點。
基本上,當你做(E[])new Object[size]
,這是一個謊言。 對象的實際運行時類是Object[]
,它不是E[]
的子類型,無論E
是什么(除非E
是Object
)。 因此,演員在理論上是不正確的。 但是,這不會立即產生任何問題,因為在Stack
類中, E
被擦除到其上限,在本例中為Object
。 所以在Stack
類中,我們可以使用elements
作為E[]
,並將E
放入並從中獲取E
,沒有問題。
只有當elements
類型為E[]
的(不正確的)事實被“暴露”到類的外部(超出E
的擦除范圍)進入某個范圍內,其中某個人具有E
的具體類型參數時,才會出現問題。 。 這通常發生在有人無意中使elements
公開,或實現一個將其返回到外部的方法時
E[] getElements() {
return elements;
}
然后在類的外部,有人有一個Stack<SomeSpecificType>
,並調用此方法,並期望SomeSpecificType[]
,這不是它得到的。
但是,您的Stack
類沒有這樣的方法。 那你怎么“暴露” elements
? 答案是elements
protected
,因此“暴露”到子類。 在這種情況下,子類MinMaxStack
使用E
的特定類型擴展Stack
,因此,它將elements
“視為”特定類型的數組,而不是。
這是重現異常所需的最小代碼。
class Stack<E> {
protected E[] elements = (E[])new Object[1];
}
class IntStack extends Stack<Integer> {
void push(Integer i) {
// subtly accessing elements as Integer[] which it's not
elements[0] = i;
}
}
Java泛型是使用類型擦除實現的,因此在編譯之后,此代碼轉換為如下所示:
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<E> {
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;
}
}
我相信通常的方法是將Class
傳遞給構造函數,並使用Array.newInstance(Class<?>, int...)
類的
public Stack(Class<E> 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<Integer> st = new Stack<>();
st.push(ran.nextInt(100));
對於早期版本,您可以指定泛型類型
Stack<Integer> st = new Stack<Integer>();
st.push(ran.nextInt(100));
現在很清楚了。 您正在嘗試創建沒有泛型類型的Stack
。 考慮Stack<Integer> st = new Stack<>();
代替。
以下是修復它的方法,你不應該做(T[]) new Object[DEFAULT_CAPACITY];
相反,抽象應該存在例如(T[]) new Comparable[DEFAULT_CAPACITY];
public class ArrayStack<T extends Comparable<? super T>> implements Stack<T> {
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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.