2015-02-12 154 views
5

我有一個示例代碼try.The代碼似乎沒有編譯錯誤。爲什麼它使用靜態嵌套類節點?當我刪除static中的Node嵌套類並編譯時,錯誤顯示create generic arrayprivate 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() { 
    } 
} 
+4

首先,你知道爲什麼通用數組是不允許的嗎? (例如'新ArrayList [5];'顯示此錯誤) – immibis 2015-02-12 01:58:21

+0

可能的重複[如何創建通用數組?](http://stackoverflow.com/questions/18581002/how-to-create-a-generic -array) – alfasin 2015-02-12 02:15:03

+0

你可以解釋爲什麼添加靜態時沒有這樣的錯誤? – Peterxwl 2015-02-12 02:18:02

回答

2

假設在您的代碼段,你正在使用的,而不是像這樣的靜態嵌套類的非靜態內部類:​​,在這種情況下,你會嘗試實例化一個Array這是不可能的, 我們不能實例化泛型類Array,因爲仿製藥沒有任何關於其在運行時類型的任何信息,而數組創建表達式指定元素類型。

那麼,爲什麼使用Static Nested Class編譯的原因是,這樣的類被視爲「頂級」類(在行爲方面):

一個靜態嵌套類的實例成員進行交互它的外部 類(和其他類)就像任何其他頂級類一樣。在 的效果中,靜態嵌套類在行爲上是一個頂級類,爲了便於打包,它已嵌套在另一個頂級類中。

現在,讓我們所有的到這一點,並回到由編譯器顯示的確切錯誤:

無法創建TrieST<Value>.Node

通用陣列這意味着,您要創建的array的類型是TrieST<Value>.Node,其運行時類型未知,因此可以將不同類型插入到next陣列中。更清楚和說明的例子可以在Cannot Create Arrays of Parameterized Types

發現而,靜態嵌套類不表現作爲內部類的TrieST<Value>,從而instiating內部Node陣列不會非法因爲它是類型TrieST<Value>.Node的不,其類型爲Node,如果它是頂級類別)。

+0

你能解釋一下爲什麼以及如何將嵌套靜態的「抑制」這個錯誤視爲頂級類? – Peterxwl 2015-02-12 02:24:50

+0

頂級類是一個非內部類,所以這意味着靜態嵌套類和外部類之間不存在隱式關係,因此實例化一個數組不會影響外部類(您的泛型類) – Tarik 2015-02-12 02:30:12

+0

@Peterxwl我剛添加了一個更新,請現在看看 – Tarik 2015-02-12 02:50:11

1

因爲使用static創建:Node[] next = new Node[R]並使用非靜態內部類創建與具有泛型類型的外部類的實例關聯的Node。禁止創建通用數組。

但是讓我們回到了幾步:

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[]superTriangle[]),它禁止創建具有泛型類型的數組,因爲它不能很好地與不變式仿製藥的性質(List<Object>List<String>)。在「Effective Java」中,Bloch提供了更詳細的解釋,如果您想深入研究。

如果您堅持使用內部類,則可以使用Array.newInstance()來解決此限制,它可以創建僅知道類型的數組在運行時如下:

private Node[] next = (Node[]) Array.newInstance(Node.class, R); 
+0

如果我仍然想在非靜態內部類中使用'Node [] next',該怎麼辦? – Peterxwl 2015-02-12 03:40:52

+0

@Peterxwl你可以欺騙編譯器:'private Node [] next =(Node [])Array.newInstance(Node.class,R);'我將它添加到答案中。 – alfasin 2015-02-12 03:43:57