Java泛型和数组构造
假设我有一个泛型类和一个泛型参数T,它是一个数字子类。我想在类构造期间初始化一个T数组。可能吗?如果是,怎么做?如果不是,为什么Java泛型和数组构造,java,arrays,generics,Java,Arrays,Generics,假设我有一个泛型类和一个泛型参数T,它是一个数字子类。我想在类构造期间初始化一个T数组。可能吗?如果是,怎么做?如果不是,为什么 public class AClass<T extends Number>{ private T array[]; private int arrayOfInt[]; public AClass(int size){ arrayOfInt = new int[size]; array = ? //
public class AClass<T extends Number>{
private T array[];
private int arrayOfInt[];
public AClass(int size){
arrayOfInt = new int[size];
array = ? //what should I put here?
}
}
公共类AClass{
专用T数组[];
private int arrayOfInt[];
公共AClass(整数大小){
arrayOfInt=新整数[大小];
array=?//我应该在这里放什么?
}
}
这是不可能的
由于Java泛型使用,运行时不知道
T
的类型,因此无法创建它的数组。T只能在编译时知道。它在运行时是未知的,因此不能初始化数组的内容。但是,您可以创建数组,每个值都将null
array = (T[]) new Number[size];
编辑:创建任何类型的实例的问题是,您需要知道您想要的默认值是什么,以及您想要调用哪个构造函数。e、 g.没有new Double()
如下所述,
double[]
将比Number[]
更高效、更快,除非您需要大的long
值,否则它将能够存储所有可能的值。除上述选项外,还可以使用或:
公共类AClass{
专用T数组[];
公共AClass(最终整数大小,T[]a){
数组=(新的ArrayList(){{
对于(int i=0;i
另外,使用反射的解决方案与Langer的泛型常见问题解答(
Utilities.createBuffer
)中建议的解决方案非常接近:如果要使用数组,有两个选项:
array=(T[])新数字[size]代码>。您必须确保永远不要将此变量返回或传递给类之外的代码,这些代码期望它是特定类型的数组,这将导致异常
array
声明为typeNumber[]
,然后只需执行array=newnumber[size]代码>。这样做的缺点是,当你从中得到任何东西时,你需要显式地转换到T
,这样才能使用它
或者,有些人会告诉您使用
ArrayList
。但在内部,ArrayList仍然是使用这两个选项之一实现的。是否有办法克服这一限制?@0verbose Yes,reflection。你需要传入一个类型为T的数组才能这样做。@Paulo:是的,没错。Yo将从数组中提取class对象,因此您也可以请求class对象。如果这样做,在使用数字[size]初始化数组之后,我可以执行array[1]=new Double()吗?(假设T当然是双倍的)。这将给你一个ClassCastException。在传递与T(不是子类)相同类型的对象后,需要使用反射来初始化数组@Ryan Amos:如果没有传递到类外的代码中,则不需要。在班里,T是erased@0verbose您已被标记,但标记不正确。只要输入这个,你就会得到通知。@Peter Lawrey:哦,是的。我懂了。A此外,A是“d”而不是“b”。)你到底为什么要那样做?你可以看看ArrayList的解决方案并实现它。@RyanAmos我不懂抱歉-你能详细说明一下吗?这是ArrayList的源代码。与其分配新内存并创建一个不相关的对象来完成任务,只需使用对象中的代码来解决您的问题:gnat-是的,我可以。这就是为什么我没有做-1。@gnat:你真的尝试过你的解决方案吗?您的代码创建的是长度为0的数组,而不是长度为size
+1的数组:谢谢您的解释。我目前计划使用Vector或ArrayList。为了完整起见:ArrayList(在Sun/OpenJDK版本中)使用第二个选项实现,使用Object[]data
。
public class AClass<T extends Number>{
private T array[];
public AClass(final int size, T[] a){
array = (new ArrayList<T>() {{
for (int i = 0; i < size; i++) {
add(null);
}
}}).toArray(a);
}
public AClass(int size, Class<T[ ]> clazz) {
array = clazz.cast(java.lang.reflect.Array.newInstance(
clazz.getComponentType( ), size));
}
public static void main(String[] args) {
System.out.println("toArray: "
+ new AClass<Double>(42, new Double[]{}).array.length);
System.out.println("java.lang.reflect.Array: "
+ new AClass<Double>(42, Double[].class).array.length);
}
}