我在Java中意识到要做通用数组,这就是"一些"人们这样做(因为它在某些情况下有效):
How to create a generic array?
那些答案(或其他在线答案)一般说有两种方法可以做到,一种是对Object []进行类型转换,另一种是使用Arrsy.newInstance(),反射,但反射需要导入Java .reflect ..等我现在可能做不到的(出于限制原因)。
MyType[] newArray = (MyType[]) new Object[size];
但是,我在运行时遇到错误:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LMyClass$MyType;
如您所见,MyType是MyClass中定义的私有类。此外,MyClass定义为:
class MyClass<K,V> {
private class MyType {
public K data;
public V data;
}
pass;
}
我猜投降失败是因为: 1,嵌套类定义 2,嵌套定义中的泛型类型?
有没有人能够解决这个问题? THX
答案 0 :(得分:1)
这是不人们的行为。人们做的是:
public <T> T[] createArray(Class<T> clazz , int capacity){
return (T[]) Array.newInstance(clazz , capacity);
}
你创建一个对象数组,期望java接受它作为T的数组。这显然不起作用(出于某种原因)。基本上演员(T[]) new Object[]
就好像我给你披萨并告诉你把它用作电视遥控器。如果这样可行,这将是可能的:
Object[] objArr = new Object[2];
objArr[0] = "abc";
objArr[1] = 23;
//lets assume the cast works.
String[] strArr = (String[]) objArr;
//what to do here? objArr[1] should be String, but
//is Integer -> no charAt
System.out.println(objArr[1].charAt(0));
答案 1 :(得分:1)
你只是误解了:
在子句MyType[] newArray = (MyType[]) new Object[size];
中,MyType不表示类标识符,而是表示类型参数,它将被声明为此YourClass<YourType>
。通用数组创建是这样的:
new K[length];
new V[length];
这是java中不允许的(允许通用数组声明(K[] genericArray
))。所以你需要用
K[] genericArray = (K[]) new Object[length];
这将导致编译器的警告。使用@SuppressWarning("unchecked")
来摆脱它。
这不太安全,所以不要让它暴露给客户端代码。
尽可能使用Paul的答案,因为它更安全。 (原因在于How to create a generic array in Java?)。仅当您无法获取或确定要创建的数组元素的运行时类时,才使用上面提到的不安全解决方案。例如,在参数化类的定义中,您无法获取type参数的运行时类,该类参数仅在编译期间起作用并且在此之后将被删除(类似E.class
的内容将无法编译),您有使用不安全的解决方法。
答案 2 :(得分:0)
使用new
创建数组时,组件类型必须是可重新类型。 MyType
是MyClass
的非静态内部类,因此当您在MyType
内编写MyClass
而没有任何限定时,它隐含地表示MyClass<K,V>.MyType
,参数化类型
通常,在这种创建参数化类型数组的情况下(注意:这与创建类型参数类型数组的问题非常不同; MyType
不是类型参数),人们会创建一个原始类型或通配符参数化类型的数组(两者都是可恢复的),并转换为参数化类型的数组类型:
MyType[] newArray = new MyClass.MyType[size];
(请注意,原始类型不只是MyType
,正如我们上面提到的那样MyClass<K,V>.MyType
。要获取原始类型,我们必须使用原始MyClass
明确限定它。 )
或
MyType[] newArray = (MyType[])new MyClass<?>.MyType[size];