我有一个try的示例代码。代码似乎没有编译错误。为什么它使用静态嵌套类节点?当我在static
嵌套类中删除Node
并进行编译时,错误会在create generic array
中显示private Node[] next = new Node[R];
。究竟发生了什么?
public class TrieST<Value> {
private static final int R = 256; // extended ASCII
private Node root; // root of trie
private int N; // number of keys in trie
// R-way trie node
private static class Node {
private Object val;
private Node[] next = new Node[R];
}
public TrieST() {
}
}
答案 0 :(得分:2)
假设您的代码片段中使用的是非静态内部类而不是静态嵌套类,如下所示:private class Node
,在这种情况下,您将尝试实例化Array
是不可能的,我们无法在泛型类中实例化Array
,因为泛型没有关于其类型在运行时的任何信息,而数组创建表达式指定元素类型。
因此,使用Static Nested Class编译的原因是这些类被视为“顶级”类(就行为而言):
静态嵌套类与其外部的实例成员进行交互 类(和其他类)就像任何其他顶级类一样。在 效果,静态嵌套类在行为上是一个顶级类 已经嵌套在另一个顶级类中以方便包装。
现在,让我们考虑所有这些,并回到编译器显示的确切错误:
无法创建
的通用数组TrieST<Value>.Node
这意味着您要创建的array
的类型是TrieST<Value>.Node
,其运行时的类型未知,因此可以在next
数组中插入不同的类型。可以在Cannot Create Arrays of Parameterized Types
然而,静态嵌套类不表现作为TrieST<Value>
的内部类,因此在Node
内部排列数组不会是非法的,因为它不属于类型TrieST<Value>.Node
,类型Node
(喜欢,如果它是顶级类)。
答案 1 :(得分:1)
因为使用static,您创建:Node[] next = new Node[R]
并使用非静态内部类创建一个与外部类的实例关联的节点,该实例具有泛型类型。并且禁止创建通用数组。
但是让我们备份几个步骤:实例化内部类(非静态)的方法如下(示例):
class TrieST<V> {
private static final int R = 256;
private Node root; // root of trie
private int N; // number of keys in trie
private TrieST<String> inst = new TrieST<String>(); // must create an instance of the outer class first
// R-way trie node
private class Node {
private Object val;
private TrieST<String>.Node next = inst.new Node(); //must use an instance of the outer class to instantiate an object of the inner class
}
public TrieST() {
}
}
现在,如果我们尝试将上面的实现从内部类的实例更改为数组,我们将获得generic array creation,因为它被禁止创建数组由于数组的协方差性质而导致的泛型类型(Shape[]
是super
的{{1}}),它不能与不变量< / em>泛型的性质(Triangle[]
不超级List<Object>
)。在&#34; Effective Java&#34;如果你想深入了解,布洛赫会提供更详细的解释。
如果您坚持使用内部类,则可以使用List<String>
来解决此限制,Array.newInstance()
可以创建仅在运行时知道的类型的数组,如下所示:
private Node[] next = (Node[]) Array.newInstance(Node.class, R);