使用非可比类创建树集:为什么是运行时异常,而不是编译时错误?

2022-09-03 04:53:41

如果我创建一个不实现Compolar的任意类,并尝试将其用作树集,则在插入对象时,它会在运行时引发异常:

public class Foo {
}

public TreeSet<Foo> fooSet = new TreeSet<Foo>();
fooSet.add(new Foo()); // Throws a ClassCastException exception here: Foo is not comparable

我不是Java专家,但是关于这个的一些事情似乎是动态类型的(ala Python),以一种我意想不到的方式。TreeSet 的实现没有办法指定其泛型类型参数必须实现可比较,以便在编译时捕获它?非泛型函数可以将接口作为参数;泛型也不可能吗?


答案 1

TreeSet之所以以这种方式实现,是因为您可以提供比较器,在这种情况下,元素不需要具有可比性。在不将实现拆分为多个类的情况下支持这两种行为的唯一方法是包含运行时检查 - 这只是该类的作者的设计决策。

公开工厂方法而不是公共构造函数将是使用更严格的泛型类型约束来维护编译时检查的一种方式,但这已经打破了核心集合API为其实现类公开公共no-arg和复制构造函数的约定。正如您在评论中指出的那样,番石榴以其收藏品走工厂路线,恕我直言,它更适合它。TreeSet


答案 2

推荐