为什么泛型数组中的 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
}
基本上,为什么我们可以使用 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
}