开发者

couldn't cast an object array to another type array

been pulling my hair for nights when I get an ClassCastException as I try to cast an object type to another object type.... I'm that sure that this code will work because all objects are are subclasses of the Object class... but somehow i get this exception...some help guys?

Sorry guys..not to be confused with the Original ArrayList, I'm learning Java programming, and practicing on casting object arrays... the exception is at line 8, where I casted the object array to a weapon array type... sorry for any form of trolling...

public class ArrayList {
    public static void main(String args[]){
       开发者_如何学编程 ArrayList arrayList = new ArrayList();
        weapon[] weapons = new weapon[5];
        for (int i = 0; i < weapons.length; i++) {
            weapons[i] = new weapon(i);
        }
        weapons = (weapon[]) arrayList.add(weapons, 
                new weapon(weapons.length + 1, "mp5"));
    }

    public Object[] add(Object[] targetObjectList, Object add){
        Object[] oldList = new Object[targetObjectList.length];
        for (int i = 0 ; i < oldList.length; i++){
            oldList[i] = targetObjectList[i];
        }
        Object[] newList = new Object[oldList.length+1];

        for (int i = 0; i < oldList.length; i++) {
            newList[i] = oldList[i];
        }
        newList[newList.length - 1] = add;
        return newList;
    }

}//end arrayList class

class weapon {
    String name;
    int id;
    public weapon(int id) {
        this.id = id;
        name = "weapon";
    }

    public weapon(int id, String name) {
        this.id = id;
        this.name = name;
    }
}


A weapon is an Object; therefore, we may treat an array af weapon as an array of Object. However, not all Objects are weapons; therefore, an array of Object may not be treated as an array of weapon - unless the thing that seems to be an array of Object really was an array of weapon to begin with. Because of this, your approach will become difficult. You could try

weapon[] newList = new weapon[oldList.length+1];

instead, but then you'd need to change all the arrays to be of type weapon[], and the method wouldn't become general (which I suppose is your goal). However, if you want a method that can add an element to any kind of array, you should use generics instead.

P.S. If you are learning about programming and arrays, writing such an add() method is a good exercise - but if you "just want it to work", you should use ArrayList instead, which does the whole job of adding for you.


Arrays are subclass of Object. You cannot cast Object[] to weapon[]. Here is a generic solution for your problem:

weapons = (weapon[])arrayList.add(weapons, new weapon(weapons.length + 1, "mp5"),weapon.class);

and

public <T> T[] add(T[] targetObjectList, T add, Class<T> c) {
    T[] oldList = (T[])Array.newInstance(c, targetObjectList.length);
    for (int i = 0; i < oldList.length; i++) {
        oldList[i] = targetObjectList[i];
    }
    T[] newList = (T[])Array.newInstance(c, oldList.length + 1);

    for (int i = 0; i < oldList.length; i++) {
        newList[i] = oldList[i];
    }

    newList[newList.length - 1] = add;

    return newList;

}

Note: Follow Java Naming Conventions. Avoid Java API class names as your class name.


  • Object o = new Foo(). This is ok. Foo is Object. As Foo extends Object
  • Foo f = new Object() Not OK, Object is NOT Foo (Compiler error)
  • Foo f = (Foo)(new Object()) - ClassCastException


What you are looking to do is known as contravariance. The inherent problem in your code is that the ARRAY that you are creating in the add function is an array of Objects (regardless of what those objects actually end up being).

If you were to do the following, your code would work. I think that you need to work with generics in this sense (look at the actual ArrayList class as it already implements this).

...snip...
    Object[] newList = new weapon[oldList.length+1];

    for (int i = 0; i < oldList.length; i++) {
        newList[i] = oldList[i];
    }
    newList[newList.length - 1] = add;
    return newList;
...snip...

Here is an example code that works much as you are anticipating it.

public class Test {

    public static void main(String[] args) {
        Integer[] i = (Integer[])Test.get();

    }

    public static Object[] get() {
        Object[] o = new Object[20];
        for(int i = 0; i < o.length; i++) {
            o[i] = new Integer(0);
        }
        return o;
        }
}

ArrayList has a method .toArray(T[] a) which will return an enlarged array size containing your new elements. So how does this contravariance work? Through the java.reflect package. This is a very small excerpt of how it actually works (there are a few different packages that work together to get down to this.)

...Object[] function(Object[] typearray) {
    Object[] o = (Object[]) Array.newInstance(typearray.getClass().getComponentType(), 20);
    ...fill...
    return o;
}

The reason you must do this is because the ARRAY (since everything in Java are objects) is an Object itself, then an Array of Objects cannot be upcasted to an Array of Integers. If you downcasted from an array of integers to an array of Objects (as shown in this above example) and then upcasted again from an Array of Objects to an Array of Integers (because we never dropped the underlying class of it being an Array of Integers).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜