为什么我在向TreeSet添加元素时没有获得类转换exception或其他东西

以下是我的代码

class NumberComparator implements Comparator { public int compare(Number o1, Number o2) { return 1; } } public class Ex28 { public static void main(String[] args) { TreeSet set = new TreeSet(new NumberComparator()); set.add(1); set.add(1.4f); set.add(1L); set.add("1a"); System.out.println(set); } } 

因为我已经定义了我自己的Number类型的比较器,但是当我添加任何其他字符串的东西时,它并没有给我任何exception。 它只是工作正常。 我得到了输出

 [1, 1.4, 1, 1a] 

任何人都可以解释它为什么会发生。

问题是一些不良做法的混合:

  • 您正在使用TreeSet的原始类型
  • 您的NumberComparator是通用的( Number是类型参数)

Number是一个类型参数这里的事实意味着类型擦除意味着你实际上不会强制转换为实Number类型。

如果将比较器更改为:

 class NumberComparator implements Comparator { public int compare(Number o1, Number o2) { return 1; } } 

和你的调用代码:

 TreeSet set = new TreeSet(new NumberComparator()); 

然后我会期待一个例外。

此外,如果您将代码更改为不使用原始类型:

 TreeSet set = new TreeSet(new NumberComparator()); 

然后你会得到一个编译时错误。

TreeSet比较器用于排序,而不是用于抛出CCE。 由于您的比较器设计为一切都返回1 ,这意味着排序不正确。

这就是你的产品没有订购的原因。

请务必阅读TreeSet构造函数的文档。

 /** * Constructs a new, empty tree set, sorted according to the specified * comparator. All elements inserted into the set must be mutually * comparable by the specified comparator: {@code comparator.compare(e1, * e2)} must not throw a {@code ClassCastException} for any elements * {@code e1} and {@code e2} in the set. If the user attempts to add * an element to the set that violates this constraint, the * {@code add} call will throw a {@code ClassCastException}. * * @param comparator the comparator that will be used to order this set. * If {@code null}, the {@linkplain Comparable natural * ordering} of the elements will be used. */ public TreeSet(Comparator comparator) { this(new TreeMap<>(comparator)); } 

它清楚地表明,如果你尝试添加除Comparator所设计的元素之外的任何其他元素,它将抛出ClassCastException如果您不通过尝试添加String使用generics可以模拟此操作 。 但是,如果您确实使用generics,那么这只是一个编译时问题。

同时,你应该始终如一地使用generics。

 class NumberComparator implements Comparator { public int compare(C o1, C o2) { return 1; // change this logic } } Set set = new TreeSet<>(new NumberComparator()); 

如果你将比较器定义如下,你会得到类抛出exception:)

 import java.util.Comparator; class NumberComparator implements Comparator { public int compare(java.lang.Number o1, java.lang.Number o2) { return 1; } }