当前位置: 首页 > 面试题库 >

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

施宏大
2023-03-14
问题内容

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

public class Foo {
}

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

我不是Java专家,但是关于此的某些事情似乎以我所没有想到的方式进行了动态类型化(例如Python)。TreeSet的实现没有办法指定其泛型类型参数必须实现Comparable以便可以在编译时捕获它吗?非泛型函数可以将接口作为参数。泛型不一样吗?


问题答案:

TreeSet之所以这样实现是因为您可以选择提供 a
Comparator,在这种情况下元素不必是Comparable。在不将实现分为多个类的情况下支持两种行为的唯一方法是包括运行时检查-
这只是该类作者的设计决定。

公开工厂方法TreeSet而不是公共构造函数将是使用更严格的泛型类型约束来维护编译时间检查的一种方法,但这与核心集合API的公开公共无参数和复制构造函数的约定有所不同。实现类。正如您在评论中指出的那样,番石榴以其系列产品走上了工厂之路,而恕我直言则更好。



 类似资料:
  • 例如如下代码: SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); Date date = sdf.parse("abcd"); 这段代码会抛出ParseException,而它是编译时异常,为什么编译阶段不报错,运行时报错?

  • 我在一个类中有一个方法,该方法具有使用泛型指定的返回类型。 对于通用返回类型,我假设上面示例中的返回将评估为: 相反,被正确返回和打印。 如果我将调用更改为: 我错过了什么,以帮助我理解这里发生了什么,为什么原始版本没有导致编译错误。

  • 问题内容: 我在类中有一个方法,该方法具有通过使用泛型指定的返回类型。 对于通用返回类型,我假设以上示例中的返回将计算为: 而是返回a并正确打印。 如果将调用更改为:我收到编译错误: 我缺少什么来帮助我了解这里发生了什么以及为什么原始版本没有导致编译错误。 问题答案: 这是因为重载解析解决了您的调用,因为没有。 请记住,Java的泛型会在运行时删除。像这样的演员阵容将被删除,并移至呼叫站点。有时这

  • 问题内容: 为什么在下面的代码中没有出现编译错误?我得到一个有点混乱的地方。是因为它们有关系吗? 问题答案: 为什么在下面的代码中没有出现编译错误? 因为编译器只关心您要强制转换的表达式的静态类型。 看这两行: 您 知道在第二行中,由于第一行,该值仅引用类型的对象,而编译器则没有。对于所有的编译器知道(编译第二线时),它 可能 实际上已经: …哪里有扩展和实现的类。因此它是有效的(在编译时),以铸

  • 我有一个超类动物和两个子类:猫和狗。Dog类有一个专属于它自己的新方法,称为playFetch()。 在运行时,我们知道会发生什么。请说服我为什么编译器不抱怨。还是我的论点正确?

  • 发生在运行时,因为编译器不能在决定执行哪个函数,但为什么编译器不能在编译时决定呢? 产出: 狗在吃...