我有课:
class SomeClass<T extends SomeInterface>{
private T[] myArray;
public SomeClass()
{
// I want to initialize myArray in here to a default size of 100
myArray = new T[100]; // this gives an error
}
}
我知道我可以通过在构造函数中要求一个参数来解决这个问题:
class SomeClass<T extends SomeInterface>{
private T[] myArray;
public SomeClass(Class<T> clazz)
{
myArray= (T[]) Array.newInstance(clazz, 100);
}
}
换句话说,为了从类SomeClass
实例化一个对象,我将不得不这样做:
SomeClass<SomeOtherClass> obj =
new SomeClass<SomeOtherClass>(SomeOtherClass.class);
我用c#编程,Java似乎不友好。我甚至不明白为什么不能将Object[]
数组转换为SomeOtherClass[]
数组。在c#中,这将是可能的......
所以我的问题是如何避免传递SomeOtherClass.class
参数,以便能够在类的构造函数中构造泛型类型的数组...
答案 0 :(得分:4)
虽然Shakedown列出了您的问题的修复程序,但请允许我解释为什么创建通用数组不是类型安全的。
我将使用Effective Java 2nd Ed。
中的示例说明原因// Why generic array creation is illegal - won't compile!
List<String>[] stringLists = new List<String>[1]; // (1)
List<Integer> intList = Arrays.asList(42); // (2)
Object[] objects = stringLists; // (3)
objects[0] = intList; // (4)
String s = stringLists[0].get(0); // (5)
让我们假装创建通用数组的第1行是合法的。
第2行创建并初始化包含单个的
List<Integer>
元件。第3行将
List<String>
数组存储到Object
数组中 变量,这是合法的,因为数组是协变的。第4行将
List<Integer>
存储到Object
数组的唯一元素中 之所以成功是因为泛型是通过擦除实现的:运行时类型 一个List<Integer>
实例只是List
,而运行时类型是。{List<String>[]
实例为List[]
,因此不会生成此分配ArrayStoreException
。 现在我们遇到了麻烦。我们存储了一个List<Integer>
实例进入一个声明只保留的数组List<String>
个实例。在第5行,我们从中检索唯一的元素 此数组中的唯一列表。编译器自动转换 检索到
String
的元素,但它是一个整数,所以我们得到一个ClassCastException
在运行时。为了防止这种情况发生 发生,第1行(创建一个通用数组)生成一个 编译时错误。
答案 1 :(得分:1)
是的,您必须像这样传递.class
才能使其发挥作用。
您可以避免所有这些,只需使用ArrayList<T>
即可。当您需要数组形式时,可以使用:(T[]) myArrayList.toArray()
答案 2 :(得分:0)
java中的所有类型都是Object类的子类,因此可以使用它来实现。
public StackArray(int size){
dataStack = (T[])new Object[size];
}