Paragraph
T有一个约束,它实现了Comparable。上面的行失败并带有异常
T[] genericArray= (T[])(new Object[2]);
如何初始化T有约束的通用数组?
答案 0 :(得分:3)
Object
未实现Comparable
。
而不是将其创建为Object[]
,而不是将其创建为Comparable[]
。
与您的评论相关:
可以声明任何类型的变量。创建数组时,您不是在数组中创建对象,而是仅分配内存来存储对象的引用。
所以你可以写:
Comparable x = "Pippo"; // Because String is Comparable
你也可以写
Comparable[] x = new Comparable[1];
x[0] = "Pippo"; // Here you add a concrete String that is a
// Comparable type on the first position
答案 1 :(得分:1)
您收到此错误是因为Object
未实现Comparable
,因此Object[]
不是Comparable[]
的子类型(因为类型擦除,它是genericArray
的运行时类型。
潜在的问题是你想要创建一个通用数组。 这在Java中是不可能的。原因是,与泛型不同,数组元素的类型在运行时是已知的。如果编写new T[]
,则不知道必须创建哪种类型的数组。
你试图通过创建一些超类型的数组来绕过这个。但这也是不正确的(如果你这样做,你应该收到警告)。如果您创建一个包含new Comparable[size]
的数组,则会创建一个Comparable
s数组,而不是某个子类型为Comparable
的数组。 T[]
可能是String[]
或Long[]
,String[]
和Long[]
的类型不同于Comparable[]
(也是在运行时)。< / p>
要演示此问题,请考虑以下程序:
public class Foo<T extends Comparable> {
T[] createArray() {
return (T[])new Comparable[1];
}
public static void main(String... args) {
Foo<String> foo = new Foo<>();
String[] ss = foo.createArray(); // here
}
}
第一眼看上去可能看起来很不错,但是当你运行它时,你得到一个ClassCastException
,因为在标记的行中Object[]
被强制转换为String[]
。
解决方案是使用Class<T>
个对象作为所谓的类型标记。这些允许您存储类型,以便您可以在运行时访问它。现在,您可以使用Array.newInstance(Class<T>, int...)
创建具有正确类型的数组。例如:
public class Foo<T extends Comparable> {
private Class<T> type;
public Foo(Class<T> type) {
this.type = type;
}
T[] createArray() {
return (T[])Array.newInstance(type, 1);
}
public static void main(String... args) {
Foo<String> foo = new Foo<>(String.class);
String[] ss = foo.createArray();
}
}
(你可能仍会收到编译器的警告,因为newInstance
的返回类型是Object
。你可以忽略它,因为它返回的对象是一个正确类型的数组。)< / p>