2012-07-11 28 views
1

我需要創建一個TreeNode類,它將能夠存儲兩種子類:String和TreeNode。 孩子的數量不固定。在變長參數列表中檢查類型

我想創建樹節點莫名其妙對象是這樣的:

TreeNode a = new TreeNode("str", new TreeNode("str2"), "str3"); //Correct 
TreeNode b = new TreeNode(a, "str4); //Correct 
TreeNode c = new TreeNode(54); //Wrong 

我該怎麼辦參數類型檢查用通配符或者在東西編譯的時候

我不當運行時解決方案:

private static final boolean debug = "true".equals(System.getProperty("debug")); 

public <T> TreeNode (T... childs) { 
    if (debug) { 
     for (Object child : childs) { 
      if (!(child instanceof String || child instanceof TreeNode)) { 
       throw new RuntimeException("Type of childs must me Tree or String"); 
      } 
     } 
    } 
} 
+0

這真的不是泛泛而談的泛泛使用。 'TreeNode'實例可以有沒有上界的異構子? – 2012-07-11 19:30:31

+0

編譯時檢查和泛型不能幫你。 'TreeNode#get()'應該返回什麼? – 2012-07-11 19:31:37

+0

TreeNode.get()返回一個字符串,這是一個子節點的控制。 – Jofsey 2012-07-11 19:37:34

回答

2

參數在構造函數應該有特殊的意義。使用可變參數是可以接受的,但它認爲這些是特殊情況。而你的問題可以用另一種方式解決。

public class TreeNode { 

    public TreeNode() { 
    //crate the object 
    } 

    public TreeNode addNode(String node, String... nodes) { 
    //Do something with string node 
    return this; 
    } 

    public TreeNode addNode(TreeNode node, TreeNode... nodes) { 
    //Do something with TreeNode 
    return this; 
    } 
} 

所以,你可以使用此類似這樣的例如

TreeNode node = new TreeNode().addNode("One","Two").addNode(node3,node4); 

,其中節點3和節點4是樹節點的instaces;

0

試試這個。

public <T> TreeNode (Object... childs) { 
    //code 
} 
+0

TreeNode c = new TreeNode(54);不應編譯 – Jofsey 2012-07-11 19:32:38

+0

在編譯時如何禁止'54'? – cklab 2012-07-11 19:32:46

2

您應該嘗試找到可添加到樹中的單個基本類型。然後,從它派生的具體節點類型:

abstract class Node { } 
class TreeNode extends Node { 
    public TreeNode(Node... children) { 
    // ... 
    } 
} 
class StringNode extends Node { 
    public StringNode(String value) { 
    // ... 
    } 
} 

用法:

TreeNode a = new TreeNode(
    new StringNode("str"), 
    new TreeNode(new StringNode("str2")), 
    new StringNode("str3")); 
+0

我可以隱式地將String轉換爲StringNode嗎? – Jofsey 2012-07-11 19:39:39

+0

@Lescott:不在Java中... – 2012-07-11 19:40:04

0

如果你想還是嫁接一定程度的編譯時類型安全的,你可以這樣做:

public class AorB<A, B> { 
    private final Object _instance; 
    private final boolean _isA; 

    public AorB(A instance) { 
    _instance = instance; 
    _isA = true; 
    } 

    public AorB(B instance) { 
    _instance = instance; 
    _isA = false; 
    } 

    public A asA() { 
    assert _isA; 
    return (A) _instance; 
    } 

    public B asB() { 
    assert !_isA; 
    return (B) _instance; 
    } 

    public boolean isA() { 
    return _isA; 
    } 
} 

然後使用AorB<String, TreeNode>實例。

請注意,您可以更進一步,也有一個類型安全的回調,如果你不喜歡,有人可能會做asB()當實例是A

public class AorB<A, B> { 
    ... 
    public interface Handler<A, B> { 
    void handle(A instnace); 
    void handle(B instance); 
    } 

    public void handle(Handler<A, B> handler) { 
    if (isA()) { 
     handler.handle(asA()); 
    } else { 
     handler.handle(asB()); 
    } 
    }