使用非Comparable类创建TreeSet:为什么运行时异常而不是编译时错误? [英] Creating a TreeSet with a non-Comparable class: why a run-time exception, rather than compile-time error?

查看:137
本文介绍了使用非Comparable类创建TreeSet:为什么运行时异常而不是编译时错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  public class Foo {
}

public TreeSet< Foo> fooSet = new TreeSet< Foo>();
fooSet.add(new Foo()); //这里抛出一个ClassCastException异常:Foo不具有可比性

我不是Java专家,但是关于这个看起来像我没有预料到的那种动态类型(ala Python)。 TreeSet的实现没有办法指定它的泛型类型参数必须实现Comparable,以便在编译时捕获它?非泛型函数可以将接口作为参数;和泛型一样是不可能的?

解决方案

TreeSet 因为你可以或者提供 Comparator ,在这种情况下,元素不需要是 Comparable 。在不将实现分成多个类的情况下支持这两种行为的唯一方法是包含运行时检查 - 这仅仅是该类作者的设计决定。



暴露 TreeSet 的工厂方法而不是公共构造函数将会是一种使用更严格的泛型类型约束来维持编译时检查的方法,但是这将会从核心集合API为其实现类公开无参数和拷贝构造函数的惯例。正如您在评论中指出的那样, Guava 带着其收藏品进入工厂路线,而恕我直言则更适合它。


If I create an arbitrary class that does not implement Comparable, and try to use it as a treeset, it throws an exception at run time when an object is inserted:

public class Foo {
}

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

I'm no Java expert, but something about this seemed dynamically typed (ala Python) in a way I wasn't expecting. Is there no way for TreeSet's implementation to specify that its generic type argument must implement Comparable so that this can be caught at compile-time? Non-generic functions can take interfaces as arguments; is the same not possible with generics?

解决方案

TreeSet is implemented that way because you can alternatively provide a Comparator, in which case the elements don't need to be Comparable. The only way to support both behaviors without splitting the implementation into multiple classes was to include runtime checks - this was simply a design decision by the author(s) of that class.

Exposing factory methods for TreeSet instead of public constructors would've been a way to maintain compile time checks using stricter generic type constraints, but that would've been a break from the core collections API's convention of exposing public no-arg and copy constructors for its implementation classes. As you noted in your comment, Guava goes the factory route with its collections and IMHO is better off for it.

这篇关于使用非Comparable类创建TreeSet:为什么运行时异常而不是编译时错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆