Java泛型类强制转换异常
我试图创建一个处理可比较数据的类。我归结为最简单的代码,当我试图实例化这个类时,它会给出一个错误。我得到了一些编译警告(未经检查的强制转换),但是当我运行这个程序时,它会抛出一个类强制转换异常。我确实看了一些关于这个话题的其他问题,但没有发现有用的东西Java泛型类强制转换异常,java,generics,comparable,Java,Generics,Comparable,我试图创建一个处理可比较数据的类。我归结为最简单的代码,当我试图实例化这个类时,它会给出一个错误。我得到了一些编译警告(未经检查的强制转换),但是当我运行这个程序时,它会抛出一个类强制转换异常。我确实看了一些关于这个话题的其他问题,但没有发现有用的东西 public class GD<Item extends Comparable<Item>> { private Item[] data; private final int MAX_SIZE = 200;
public class GD<Item extends Comparable<Item>> {
private Item[] data;
private final int MAX_SIZE = 200;
public GD() {
data = (Item[]) new Object[MAX_SIZE];
}
public static void main(String[] args) {
GD<String> g = new GD<String>();
}
}
公共类GD{
私有项[]数据;
私人最终整数最大值=200;
公共GD(){
数据=(项目[])新对象[最大大小];
}
公共静态void main(字符串[]args){
GD g=新的GD();
}
}
问题在于:
data = (Item[]) new Object[MAX_SIZE];
您正在实例化一个对象
数组,然后尝试将其转换为项
数组,这会引发异常,因为对象
没有扩展项
类,因为它没有实现可比
。您想要的是:
data = new Item[MAX_SIZE];
但是您不能这样做,因为Item
是泛型类型。如果要动态创建此类型的对象(或对象数组),需要将类
对象传递给GD类的构造函数:
import java.lang.reflect.Array;
public class GD<Item extends Comparable<Item>> {
private Item[] data;
private final int MAX_SIZE = 200;
public GD(Class<Item> clazz) {
data = (Item[]) Array.newInstance(clazz, MAX_SIZE);
}
public static void main(String[] args) {
GD<String> g = new GD<String>(String.class);
}
}
import java.lang.reflect.Array;
公共类GD{
私有项[]数据;
私人最终整数最大值=200;
公共GD(课堂){
data=(Item[])Array.newInstance(clazz,MAX_SIZE);
}
公共静态void main(字符串[]args){
GD g=新的GD(String.class);
}
}
问题在于:
data = (Item[]) new Object[MAX_SIZE];
您正在实例化一个对象
数组,然后尝试将其转换为项
数组,这会引发异常,因为对象
没有扩展项
类,因为它没有实现可比
。您想要的是:
data = new Item[MAX_SIZE];
但是您不能这样做,因为Item
是泛型类型。如果要动态创建此类型的对象(或对象数组),需要将类
对象传递给GD类的构造函数:
import java.lang.reflect.Array;
public class GD<Item extends Comparable<Item>> {
private Item[] data;
private final int MAX_SIZE = 200;
public GD(Class<Item> clazz) {
data = (Item[]) Array.newInstance(clazz, MAX_SIZE);
}
public static void main(String[] args) {
GD<String> g = new GD<String>(String.class);
}
}
import java.lang.reflect.Array;
公共类GD{
私有项[]数据;
私人最终整数最大值=200;
公共GD(课堂){
data=(Item[])Array.newInstance(clazz,MAX_SIZE);
}
公共静态void main(字符串[]args){
GD g=新的GD(String.class);
}
}
很简单:对象
不实现可比
,但您强制执行项扩展可比
。因此,不能将对象[]
强制转换为项[]
为了避免创建泛型类型Item
的数组的问题,我们可以看看Java的实现。此处,支持数组的类型为Object
,只能通过以下方式访问:
由于只允许插入项
s,因此只能返回项
s,因此永远不会有类异常
关于代码的一些注释:通常,类型参数使用
T
、U
、S
。如果使用类似于Item
,可能会将类型参数与acutal类混淆。很简单:对象
不实现可比
,但您强制执行Item扩展可比
。因此,不能将对象[]
强制转换为项[]
为了避免创建泛型类型Item
的数组的问题,我们可以看看Java的实现。此处,支持数组的类型为Object
,只能通过以下方式访问:
由于只允许插入项
s,因此只能返回项
s,因此永远不会有类异常
关于代码的一些注释:通常,类型参数使用T
、U
、S
。如果您使用类似于Item
,可能会将类型参数与acutal类混淆。强制转换(Item[])
不会根据Item[]
检查对象的运行时类型,因为运行时不知道Item
是什么;相反,它检查项[]
的擦除情况,该项为可比[]
(因为可比
是对项
的擦除)。实际运行时类为object[]
的对象不是Comparable[]
的实例,因此它会导致ClassCastException
。这就是为什么要这么做
data = (Item[]) new Comparable[MAX_SIZE];
将使例外消失
因此,有两种方法可以实现这一点:
- 类型理论上是“安全”的方式,即使用固定的非特定数组类型,如
或Object[]
作为Comparable[]
变量的编译时类型。这样,您就可以创建相同运行时类型的数组对象,并安全地将其分配给变量,而无需进行不安全的强制转换。但是,当需要从数组中取出某些内容并将其作为泛型类型返回时,必须执行显式(未选中)强制转换:数据
(Item[])
不会根据Item[]
检查对象的运行时类型,因为运行时不知道Item
是什么;相反,它检查项[]
的擦除情况,该项为可比[]
(因为可比
是对项
的擦除)。实际运行时类为object[]
的对象不是Comparable[]
的实例,因此它会导致ClassCastException
。这就是为什么要这么做
data = (Item[]) new Comparable[MAX_SIZE];
将使例外消失
因此,有两种方法可以实现这一点:
- 类型理论上是“安全”的方式,即使用固定的非特定数组类型,如
或Object[]
作为Comparable[]
变量的编译时类型。这样就可以创建一个数组对象数据