通用数组在直接引用时抛出ClassCastException(在通过helper方法调用时不会抛出)

Vis*_*ium 9 java arrays generics casting

这太神奇了!看看这个简单的代码:

public class ArrayOFMagic<T> {

    protected T[] array;

    protected int showMeYouRLength() {
        return array.length;
    }

    ArrayOFMagic() {
        array = (T[]) new Object[10];
    }

    protected void set(T value, int index) {
        array[index] = value;
    }

    public static void main(String[] args) {
        ArrayOFMagic<Integer> arrayOFMagic = new ArrayOFMagic<Integer>();
        System.out.println(arrayOFMagic.showMeYouRLength());
        System.out.println("MAGIC INCOMING");
        System.out.println(arrayOFMagic.array.length);
    }

}
Run Code Online (Sandbox Code Playgroud)

输出:

10
MAGIC INCOMING
线程"main"中的异常java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为[Ljava.lang.Integer; 在ArrayOFMagic.main(ArrayOFMagic.java:25)

我两次调用array.length.一次通过方法,直接一次.它在使用方法时继续,并在直接调用时抛出异常.Oo有人解释?

编辑:只是为了澄清:当没有直接调用时,类工作正常.你可以在数组元素和所有..上设置setter/getter!

Kyl*_*lar 6

更新答案:

免责声明:这个答案不是来自我,我问过一位前Sun员工,他在Java中使用泛型,为什么会这样.他的回答是:

第一个调用从泛型类本身内部访问该成员,该成员被擦除到它的下界(在本例中为Object),因此在ref到array.length中没有强制转换.

但第二个调用是在泛型类型参数化实例上,因此类型变量(数组)绑定到Integer.

数组字段声明为T []类型,它绑定到Integer [].编译器发出的访问器代码将其强制转换为该类型,并且强制转换(在每个单词的意义上).

老答案: 这是实现课程的更好方法(作为zhong.j.yu答案的补充).

import java.util.ArrayList;
import java.util.List;

public class NotSoMagical<T> {

    public List<T> arrayList;

    protected int length() {
        return arrayList.size();
    }

    NotSoMagical() {
        arrayList = new ArrayList<T>(10);
    }

    protected void set(T value, int index) {
        arrayList.set(index, value);
    }

    public static void main(String[] args) {
        NotSoMagical<Integer> notMagicalAtAll = new NotSoMagical<Integer>();
        System.out.println(notMagicalAtAll.length());
        System.out.println("MAGIC INCOMING");
        System.out.println(notMagicalAtAll.arrayList.size());
    }

}
Run Code Online (Sandbox Code Playgroud)