这就是我要做的事情:
import java.lang.reflect.*;
class exampleOuter <T extends Number>
{
private exampleInner<T>[] elements;
public exampleOuter(Class<T> type, int size)
{
elements = (exampleInner<T>[]) Array.newInstance(type, size);
}
}
有人告诉我,如果我想创建T类通用数组,我应该使用
elements = (T[]) Array.newInstance(type,size);
所以我试着将它扩展到我的自定义类并得到一个ClassCastException(Ljava.lang.Double;不能转换为L mypackagename .exampleInner;我在main中声明这个类就像这样:
exampleOuter<Double> test = new exampleOuter(Double.class,15);
我可以声明内部类很好,我也可以声明不是innerClass通用的数组,所以我想它是outerClass的构造函数中的东西。有什么想法吗?
编辑: 我明白问题是什么。当我创建一个新的数组实例时,我创建了一个双精度数组,而不是exampleInner。我认为。如果这是正确的,我需要找到一种方法来创建一个exampleInner数组,同时只将Double.class传递给函数。
编辑2: 我意识到通用数组不是类型安全的,但无论如何我必须使用它们,因为我的老师要求我们使用它们。
编辑3: 有人告诉我,要使用通用数组,我必须以这种方式分配它们,我认为这样做需要反思。编译器告诉我该类正在使用不安全或未经检查的操作,但我必须使用通用数组,这就是我所知道的。如果有更好的方法我会更改代码。
答案 0 :(得分:1)
这是我提出的解决方案:
public exampleOuter(Class<T> type, int size)
{
innerClass<T> aux = new innerClass<T>();
elements = (exampleInner<T>[]) Array.newInstance(aux.getClass(), size);
}
我认为这也有用:
elements = (exampleInner<T>[]) Array.newInstance(innerClass<T>.class, size);
但它没有,可能是因为泛型在Java中的实现(类型擦除等等)。
第一种方法的问题是我被迫创建一个新对象并实例化,尽管不是真的需要它。另外,它使代码更加臃肿imo。
编辑:第二种方法无效,因为我使用的是innerClass<T>.class
而不是innerClass.class
。感谢您的建议,我现在就用它。
答案 1 :(得分:0)
您正在为某些特定T
创建T[]
类型的对象,并将其分配给类型为exampleInner<T>[]
的字段,这将是一个错误。
对于T extends Number
:T[]
的删除类型为Number[]
;已删除的exampleInner<T>[]
类型为exampleInner[]
。但编译器警告应该表明你无论如何都做错了。
但你几乎肯定不需要反思,所以不要使用它。
答案 2 :(得分:0)
T extends Number,你试图将它转换为exampleInner,我怀疑它是在Number层次结构中的正确位置。
在没有exampleInner的情况下尝试一下。或者尝试将exampleInner作为exampleOuter构造函数的类型参数传递。
答案 3 :(得分:0)
这里没有“通用阵列创建”。数组的组件类型是“exampleInner”(好吧,它应该是exampleInner,但是数组组件类型必须是“reified types”,因此它不能存储在运行时。),这在编译时是已知的。所以你不需要传入Double.class参数。
您真正需要做的是创建一个参数化类型的数组。一种方法是创建一个原始类型的数组,并将其转换为参数化数组类型。这将允许您像往常一样使用数组,并获得泛型的好处,当你把东西拿出来时,不必投射。
从技术上讲,这是一个未经检查的强制转换,因为它理论上可能会在以后引起意外问题,因为它无法阻止您将错误类型的对象放入数组中。但是因为这是你班级中的一个私有变量,我假设你只是在你的类中操作它,如果你相信自己的代码正确使用它,那么它就可以工作。
import java.lang.reflect.*;
class exampleOuter <T extends Number>
{
private exampleInner<T>[] elements;
@SuppressWarnings("unchecked")
public exampleOuter(int size)
{
elements = (exampleInner<T>[]) new exampleInner[size];
}
}