为什么泛型数组中的 setter 方法有效(JAVA)?

Why does setter method in generic array work(JAVA)?

基本上,为什么我们可以使用 setter 方法在 class 内分配泛型数组的值,但每当我们尝试在泛型 class 之外访问它时它会抛出运行时错误?

class Demo<T>{
    T d[]=(T[])new Object[3];
    T x;
    int l=0;
    void setD(T x){
        d[l++]=x; //Why does this work?
    }
    void getD(int x){
        System.out.println(d[x]); //Why does this work too? as i cant print in main class directly
    }

}

public class Main<T> {

    public static void main(String[] args) {

        Demo<Integer> de=new Demo<>();
        de.x=7; //This doesnt throw any error

        //de.d[0]=3; //This throws runtime error. Runtime error is given below.. I understand why this doesn't work 
//but i wanted to know why does that setter method work as this line of code seems similar to that of setter method
        de.setD(3);

        de.getD(0);

    }
}

线程“主”中的异常java.lang.ClassCastException:class [Ljava.lang.Object;无法转换为 class [Ljava.lang.Integer; ([Ljava.lang.Object;和 [Ljava.lang.Integer;在加载程序 'bootstrap' 的模块 java.base 中) 在 com.company.Main.main(Main.java:34)

为什么会这样?

当您将其作为通用参数获取时,会隐式转换为 Integer 对象。可以通过instanceof Integer in void.

查看

我认为这是因为类型擦除。看看这一行。

Demo<Integer> de=new Demo<>();
de.d[0]=3; //java knows, that de.d should be Integer[], but it actually is Object[]

这里,因为指定了泛型参数,所以java期望de.d是Integer[]。但它实际上是 Object[]。 java 尝试将对象数组视为整数数组。

为此,java 必须将 Object[] 转换为 Integer[] 。它抛出一个异常。 如果您执行以下操作,则会抛出相同的异常

Integer[] ints = (Integer[])new Object[10];

在你的内心class应用了类型擦除。因此,java 在运行时将 T 视为对象。所以这个方法

T d[]=(T[])new Object[3];
void setD(T x){
    d[l++]=x; //Why does this work?
}

将一个 x,它是对象数组。将 Integer 转换为 Object 没有问题,也无需将 Object[] 转换为 Integer[] 。所以,一切正常。 方法中的代码相当于如下

Object d[]= (Object[])new Object[3];
void setD(Object x){
    d[l++]=x; // x is Integer here
}