为什么静态嵌套类?

时间:2015-02-12 01:56:45

标签: java

我有一个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() {
    }
}

2 个答案:

答案 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);