如何创建一个项目数组,其条目具有通用字段?
How can I create an array of items whose entries have generic fields?
我有这个代码:
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];
}
}
但后来我收到一条错误消息:
Main.java:17: error: generic array creation
a = new Entry[size];
^
是否可以创建该数组?
因为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);
}
}
其实你可以通过 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);
}
}
我同意 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);
}
}
作为内部 class,Entry
类型在封闭 class 中声明的类型参数 Key
的范围内。换句话说,Entry
也是通用的。
您可以使用
a = (Entry[]) new Foo<?>.Entry[size];
或原始的等价物(我不推荐)
a = (Entry[]) new Foo.Entry[size];
这种array creation在JLS
中有解释
ArrayCreationExpression:
new ClassOrInterfaceType DimExprs [Dims]
陈述
It is a compile-time error if the ClassOrInterfaceType
does not denote
a reifiable type (§4.7).
其中 reifiable type 是
A type is reifiable if and only if one of the following holds:
- It refers to a non-generic class or interface type declaration.
- It is a parameterized type in which all type arguments are unbounded wildcards (§4.5.1).
- It is a raw type (§4.8).
- It is a primitive type (§4.2).
- It is an array type (§10.1) whose element type is reifiable.
- It is a nested type where, for each type
T
separated by a ".", T
itself is reifiable.
通过使用带通配符或原始类型的参数化,我们可以得到上面给出的数组创建表达式。
我有这个代码:
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];
}
}
但后来我收到一条错误消息:
Main.java:17: error: generic array creation
a = new Entry[size];
^
是否可以创建该数组?
因为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);
}
}
其实你可以通过 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);
}
}
我同意 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);
}
}
作为内部 class,Entry
类型在封闭 class 中声明的类型参数 Key
的范围内。换句话说,Entry
也是通用的。
您可以使用
a = (Entry[]) new Foo<?>.Entry[size];
或原始的等价物(我不推荐)
a = (Entry[]) new Foo.Entry[size];
这种array creation在JLS
中有解释ArrayCreationExpression: new ClassOrInterfaceType DimExprs [Dims]
陈述
It is a compile-time error if the
ClassOrInterfaceType
does not denote a reifiable type (§4.7).
其中 reifiable type 是
A type is reifiable if and only if one of the following holds:
- It refers to a non-generic class or interface type declaration.
- It is a parameterized type in which all type arguments are unbounded wildcards (§4.5.1).
- It is a raw type (§4.8).
- It is a primitive type (§4.2).
- It is an array type (§10.1) whose element type is reifiable.
- It is a nested type where, for each type
T
separated by a ".",T
itself is reifiable.
通过使用带通配符或原始类型的参数化,我们可以得到上面给出的数组创建表达式。