object数组到参数化类型的转型将在编译期产生警告,运行时产生异常 但是为什么java类库确有很多这个用法,而且没有任何运行时异常????
请看下面一个例子:
public class GenericArray<T> { private T[] arry;
public GenericArray(int size){
arry=(T[])new Object[size];
}
public void put(int index,T item){
arry[index]=item;
}
public T get(int index) {return arry[index];}
public T[] rep(){return arry;}
public static void main(String[] args) {
GenericArray<Integer> gai=new GenericArray<Integer>(10);
Integer[] ia=gai.rep();
//Object [] oa=gai.rep(); }}
编译没有任何问题,但运行时会有:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
at GenericArray.main(GenericArray.java:15)
我知道,这里有个檫除的问题,构造函数
public GenericArray(int size){
arry=(T[])new Object[size];
}
这里返回的其实应该是object类型,但是如果我把main函数里这一句:
Integer[] ia=gai.rep();改成Integer[] ia=(Integer[])gai.rep();还是一样出错!!!!Object是所有类的父类,我把Object类向下转型有什么不可以?!!!这种方式在java类库中应该很多啊.....

解决方案 »

  1.   

    向下转型的前提是:该对象本来就是那个类型的,只是引用变量是父类型。比如:
    Object[] objs = new Integer[10]; // 本来它就是Integer型数组
    Integer[] as = (Integer[]) objs; // 恢复庐山真面目你这种定义是不行的:
    Object[] objs = new Object()[10]; // 本来它就是个Object数组
    Integer[] as = (Integer[]) objs; // 没啥好恢复的了
    我想你可能理解错了Java类库中的用法,这个是可以的:
    objs[0] = new Integer(1); // 用Object变量保存了Integer实例
    Integer a = (Integer) objs[0]; // 恢复庐山真面目
      

  2.   

    think in java 里边这样讲: 遗憾的是,如果查看Java SE5标准类库中的源代码,你就会看到从Object数组到参数化类型的转型遍及各处。例如,下面是经过整理和简化之后的从collection中复制ArrayList的构造器:
    publiic ArratList(Collection c){
    size=c.size();
    elementData=(E[])new Object[size];
    c.toArray(elementData);
    }这里边Object是直接创建的,然后立马就向下转型了 为什么可以这样呢?
      

  3.   

    这个精简貌似过渡精简了我实际看到的源码,ArrayList本来就是用Object[]来管理所有元素的:private transient Object[] elementData;只不过是在最终输出为指定类型数组的时候,做了转换:
    public <T> T[] toArray(T[] a) {
      return (T[]) Arrays.copyOf(elementData, size, a.getClass()); // 精简了下,只保留一行
    }
    然后是 Arrays.copyOf():
    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
            T[] copy = ((Object)newType == (Object)Object[].class)
                ? (T[]) new Object[newLength]
                : (T[]) Array.newInstance(newType.getComponentType(), newLength);
            System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
            return copy;
    }
    那么还要看看Array.newInstance()是怎么根据类型来创建数组的:
    public static Object newInstance(Class<?> componentType, int length) throws NegativeArraySizeException {
    return newArray(componentType, length);
    }继续刨根问底:
    private static native Object newArray(Class componentType, int length) throws NegativeArraySizeException;
    结束
      

  4.   

    恩 耐心大体看了下  但是我还是不明白elementData=(E[])new Object[size];
    按理讲这个语法是不对的 会不会是tranisent关键字修饰elementData的缘故???我对这个关键字不了解。这个Object数组是现场创建的,里面放的并不是它的子类的引用,现在就直接下转型了。真的不懂............
      

  5.   

    我的意思很简单,源码里面根本没有:
      elementData=(E[])new Object[size];
    这句话。
    自己去Eclipse里面找源码看看就知道了。