我有这段代码:
constant
当我编译它时,我收到一个错误,说:
import java.util.*;
import java.lang.*;
import java.io.*;
class Main{
public static void main (String[] args){
Foo<String> foo = new Foo<String>(1000);
}
}
class Foo<Key extends Comparable<Key>>{
private Entry[] a;
private class Entry{
Key key;
}
public Foo(int size){
a = (Entry[])new Object[size]; // <- this is the problem
}
}
我试过了:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LFoo$Entry;
at Foo.<init>(Main.java:17)
at Main.main(Main.java:7)
但后来我发了一个错误说:
import java.util.*;
import java.lang.*;
import java.io.*;
class Main{
public static void main (String[] args){
Foo<String> foo = new Foo<String>(1000);
}
}
class Foo<Key extends Comparable<Key>>{
private Entry[] a;
private class Entry{
Key key;
}
public Foo(int size){
a = new Entry[size];
}
}
是否可以创建该数组?
答案 0 :(得分:1)
因为Generics don't cope very well with arrays(在编译时)。
您应该使用一些Collection,而不是:
class Foo<Key extends Comparable<Key>> {
private List<Entry> a;
private class Entry {
Key key;
}
public Foo(int size) {
a = new ArrayList<Entry>(size);
}
}
答案 1 :(得分:1)
嗯,实际上你可以通过reflection
:
public class Main {
public static void main(String[] args) {
Foo<String> foo = new Foo<String>(1000);
foo.a[0] = foo.new Entry();
foo.a[0].key = "ss";
}
}
class Foo<Key extends Comparable<Key>> {
public Entry[] a;
public class Entry {
Key key;
}
public Foo(int size) {
a = (Entry[]) java.lang.reflect.Array.newInstance(Entry.class, size);
}
}
答案 2 :(得分:1)
我同意kocko你应该使用一些Collection
而不是数组。但具体到你的观点,这为我编译并运行。这只是将创建数组的责任推迟到Array.newInstance
方法。缺点是它迫使演员
class Foo<Key extends Comparable<Key>>{
private Entry[] a;
private class Entry{
Key key;
}
public Foo(int size){
a = (Entry[])Array.newInstance(Entry.class,size);
}
}
答案 3 :(得分:0)
作为内部类,Entry
类型在封闭类中声明的类型参数Key
的范围内。换句话说,Entry
也是通用的。
您可以使用
a = (Entry[]) new Foo<?>.Entry[size];
或原始等价物(我不推荐)
a = (Entry[]) new Foo.Entry[size];
这种类型的array creation在JLS中解释
ArrayCreationExpression: new ClassOrInterfaceType DimExprs [Dims]
说明
如果
ClassOrInterfaceType
未表示,则为编译时错误 可再生类型(§4.7)。
当且仅当下列之一成立时,类型才可以恢复:
- 它指的是非泛型类或接口类型声明。
- 这是一种参数化类型,其中所有类型参数都是无界通配符(§4.5.1)。
- 这是一种原始类型(§4.8)。
- 这是一种原始类型(§4.2)。
- 它是一种数组类型(第10.1节),其元素类型是可以恢复的。
- 这是一种嵌套类型,对于以“。”分隔的每种类型
T
,T
本身都是可以恢复的。
通过使用带通配符或原始类型的参数化,我们可以得到上面给出的数组创建表达式。