Java泛型转换错误
与标题相对应,我的问题是获取泛型数组的数组长度,该数组位于类的实例中,该类已使用此泛型类型初始化。 当我想要获取数组的长度(ak.array.length)时,java会抛出以下错误: 线程“main”java.lang.ClassCastException中的异常:[Ljava.lang.Object;无法转换为[Ljava.lang.String; 位于Testclass.main(Testclass.java:15) 那么我的错误在哪里呢? 提前谢谢Java泛型转换错误,java,generics,classcastexception,Java,Generics,Classcastexception,与标题相对应,我的问题是获取泛型数组的数组长度,该数组位于类的实例中,该类已使用此泛型类型初始化。 当我想要获取数组的长度(ak.array.length)时,java会抛出以下错误: 线程“main”java.lang.ClassCastException中的异常:[Ljava.lang.Object;无法转换为[Ljava.lang.String; 位于Testclass.main(Testclass.java:15) 那么我的错误在哪里呢? 提前谢谢 public class Testcl
public class Testclass {
static class ArrayKeeper<T> {
protected T[] array;
public ArrayKeeper() {
array = (T[])new Object[5];
}
}
public static void main(String[] args) {
//create a new instance of inner class ArrayKepper (type String)
Testclass.ArrayKeeper<String> ak = new Testclass.ArrayKeeper<String>();
System.out.println(ak.array.length); //cast error here.
}
}
公共类Testclass{
静态类阵列保持器{
受保护的T[]阵列;
公共ArrayKeeper(){
数组=(T[])新对象[5];
}
}
公共静态void main(字符串[]args){
//创建内部类ArrayKepper的新实例(类型字符串)
Testclass.ArrayKeeper ak=新的Testclass.ArrayKeeper();
System.out.println(ak.array.length);//此处强制转换错误。
}
}
我认为您需要在ArrayKeeper
中实现length
getter,因为您无法将对象[]
强制转换为字符串[]
,调用ak.array
会尝试执行该强制转换。问题在于这一行:
array = (T[]) new Object[5];
这不是创建泛型数组的方法,您正在创建一个对象[]
,而不是您想要的字符串[]
。您不能创建一个对象[]
,然后将其强制转换为您想要的任何类型,您必须创建一个正确类的数组。请尝试以下方法:
public ArrayKeeper(Class<T> clazz, int size) {
array = (T[]) Array.newInstance(clazz, size);
}
根据我的理解:array=(t[])新对象[5];是否已执行强制转换?否。由于运行时的类型擦除,在该点上不会发生实际强制转换。(在类型擦除之后,
t
变为Object
)Meh.比基于反射的方法更好的方法是只使用API隐藏强制转换。例如,看看Java中ArrayList
的实现:它由一个普通的Object[]
支持,对象在调用get(int)时强制转换
等等。只要避免暴露强制类型转换,您就会被设置。反射速度很慢,需要您传递和跟踪大量完全冗余的类
对象。最好的选择可能是使用列表
而不是数组,但如果失败,则会将API与传递类
混为一谈对象只是很笨拙。@LouisWasserman反射不像以前那么慢了(这是一个常见的误解),此外,如果您不知道预期用途,并且还没有对其进行分析,您如何知道这是否会很慢?W.r.t.传递类对象,这是一个非常常见的习惯用法,在Java的API本身中到处都在使用。在Java API的哪些部分?在集合框架中没有任何地方,尽管有值得注意的(值得注意的)特性除了EnumMap
和EnumSet
之外。我承认反射比以前快得多,而且我相信数组。newInstance
习惯用法实际上在AbstractCollection.toArray(T[]中使用)
。但是……如果你坚持,这里还有另一个论点:如果T
本身是一种泛型,那该怎么办?你在回答中描述的方法阻止你使用泛型T
@LouisWasserman请先读一遍。
Testclass.ArrayKeeper<String> ak =
new Testclass.ArrayKeeper<String>(String.class, 5);