2010-08-03 47 views
0

我与树的在Java中工作,我有一个简单的无序树下面的接口与自我参考:如何避免参数类型警告自引用java中的类型安全接口?

public interface Node<N extends Node> { 

    public N getParent(); 
    public void setParent(N parent); 

    public Collection<N> getChildren(); 

    public void addChild(N node); 
    public void removeChild(N node); 

    public N getRootNode(); 

    ... more ... 
} 

课程的想法是创建一个类型安全的节点

public abstract class ParentChildNode<E extends Node> implements Node<E> { 

问题这真的让我很烦,被警告,我得到:

ParentChild is a raw type. References to generic type Node<N> should be parameterized 

warning on this line: 

public interface Node<N extends Node> { 

warning on this line: 

    public abstract class ParentChildNode<E extends ParentChild> implements ParentChild<E> 

我可以这样做:

public interface Node<N extends Node<?>> { 

但我担心im踩到yuckness领土。我可以压制警告,但那不允许我在哪里工作。

有什么建议吗?我注意到java.util集合API在任何地方都没有任何警告。

在此先感谢

回答

3

怎么是这样的(平行的Enum类的声明):

public interface Node<N extends Node<N>> { 

    public N getParent(); 
    public void setParent(N parent); 

    public Collection<N> getChildren(); 

    public void addChild(N node); 
    public void removeChild(N node); 

    public N getRootNode(); 

    ... more ... 
} 

public abstract class ParentChildNode implements Node<ParentChildNode> { 
1

您的类型是无限递归。所有的节点都是Node<Node<Node<Node<…>>>>或者一些同样无限的子类型。 Java的泛型不足以处理这些事情。

此外,如果您有这些节点的树,那么根类型是什么?它没有父母。我想你可能有一个类型NullNode<GodKnowsWhat>,但这只是推迟了问题。我想根可以简单地返回null作为父母,但这是颠覆整个层次结构。

你可以有什么,而不是: 我能走到今天:

public interface Node { 
    public Collection<ChildNode<Node>> getChildren(); 

    public void addChild(ChildNode<Node> node); 
    public void removeChild(ChildNode<Node> node); 
} 

public interface ChildNode<Parent> extends Node { 
    public Parent getParent(); 
    public void setParent(Parent parent); 
} 

Node的方法的类型是错误的。你不能用Java来做到这一点。如果你真的想尝试Scala。它运行在JVM上,它的类型系统要复杂得多。我相当肯定它会允许你需要的类型递归。另外,你可能能够在C++中关闭它。 C++也有一个更强大的类型系统,但我没有足够的了解它是否会让你用这种术语来做这种事情。

相关问题