我的一个应用程序曾经抛出一个 IllegalArgumentException ,指出比较方法违反了它的一般合同。我找到了一些详细说明问题的来源,例如http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6804124和http://www.oracle.com/technetwork/java/javase/compatibility-417013。 html#source并想在我的应用程序中解决这个问题。
但我无法重现该问题,因此无法知道我的修复是否正确。
在我努力重现的过程中,我试图尽可能地简化问题,并提出了一个如下所示的小类:
public class Sortee implements Comparable<Sortee>
{
/** a value to sort by */
public final int _x;
public Sortee(int x)
{
_x = x;
}
public int compareTo(Sortee o)
{
return 1;
}
}
我还创建了一个等价的比较器:
public class SorteeIncorrectComparator implements Comparator<Sortee>
{
public int compare(Sortee a, Sortee b)
{
return 1;
}
}
在另一个类中,我创建了一个 Sortee 对象列表并调用 Collections.sort() 变体来引发 IllegalStateException:
private static void sort()
{
List<Sortee> sortees = createSortees();
Collections.shuffle( sortees );
Collections.sort( sortees, new SorteeIncorrectComparator() );
Collections.shuffle( sortees );
Collections.sort( sortees );
}
但是永远不会引发 IllegalStateException。
我已经在 Linux 和 Windows 上以及在 Windows 上使用 Java 1.7.0_21、23.21-b01 的 Eclipse 中进行了尝试,并检查了属性 java.util.Arrays.useLegacyMergeSort 是否未设置。
我认为在 compare 方法中总是返回 1 应该会破坏契约,因为它既不是可交换的也不是传递的。
为什么我永远不会收到 IllegalStateException?