【问题标题】:How to prevent node of another generic type or a raw node to be added to a BST?如何防止将另一个泛型类型的节点或原始节点添加到 BST?
【发布时间】:2015-10-19 17:53:39
【问题描述】:

我正在实现一个不允许重复的通用 BST。我创建了一个Node 类,其定义如下:

class Node<T extends Comparable<T>> implements Comparable<Node<T>>{
    private T value;
    // other stuff
}

有了它,我基本上希望与某个节点关联的值可以与相同类型的其他值进行比较。然后我里面还有下面compareTo方法:

@Override
public int compareTo(Node<T> o) {
    return value.compareTo(o.value);
}

现在,在我的 BST 的实施中,我在接受参数方面遇到了问题。 BST 的定义如下:

public class BinaryTreeSet<T extends Comparable<T>> {
    private Node<T> root;
    // other stuff
}

如您所见,我要求根的泛型类型与相同泛型类型的其他值可比较,即T extends Comparable&lt;T&gt;。这似乎一切正常,直到我的 add 方法的实现,它具有以下签名:

public void add(Node<T> n) {...}

似乎没有什么可疑的(至少对我而言),但如果我有以下代码:

BinaryTreeSet<String> t = new BinaryTreeSet<>();
t.add(new Node(12));  // Adding a raw Node (whose value is actually an integer)

它实际上可以编译,但它不应该编译,因为我正在实例化 Strings 的 BinaryTreeSet,所以我应该无法将数字添加到树中。

我做错了什么,为什么?在这些情况下如何使其无法编译?

【问题讨论】:

  • 至少,有一个警告。
  • Java 泛型无法处理原始类型。永远不要使用 rawtypes,你不会有这个问题。使用 rawtypes 并忽略所有编译器警告,编译器无能为力 - 事实上这就是为什么会有 rawtype 编译器警告......
  • @BoristheSpider 我永远不会使用原始类型,但也许这个类的客户会,这就是为什么我问是否有办法防止这种行为......
  • AFAIK 您无法在代码中阻止这种情况,但如果您对构建环境有任何控制权,则可以使用-Xlint:rawtypes-Werror 来生成错误.

标签: java generics binary-search-tree raw-types


【解决方案1】:

没有办法防止这种情况发生,因为 Java 在运行时不保留泛型类型信息。当程序执行时,value 是一个Object,因此可以同时持有一个Integer 和一个String

实践中的解决方案是简单地从您的代码中禁止原始类型。几乎没有理由在现代 Java 应用程序中使用它们,然后只在经过良好测试和限制可见性的库代码中使用它们。从不应用程序逻辑。如果您应该使用原始类型,javac 已经发出警告,您最好不要忽略它们。

正如 ApproachingDarknessFish 所指出的,如果您使用原始类型,您可以强制 javac 失败,方法是这样调用它:

javac -Xlint:rawtypes -Werror ....

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多