使用JRE 1.7排序时哪个类抛出IllegalArgumentException?

时间:2012-10-23 21:33:07

标签: java sorting java-7 illegalargumentexception

我在Java7中使用Collections.sort()得到了(显然是臭名昭着的)IllegalArgumentException 多亏了我理解原因,这基本上是(咳嗽)糟糕的代码 问题是,我无法自己重现异常。我做了一些jdk源代码挖掘,并找到了哪个类抛出异常。我们的想法是创建相应的测试用例。

顺便说一句,这是代码 <骄傲等级=" 0" >

@Override
public int compareTo( Symbol other) {
    if( this.lastUse == 0) {
        if( other.lastUse != 0) return (int)( -DateMicros.ONE_DAY);
    } else if( other.lastUse == 0) {
        return ( int)DateMicros.ONE_DAY;
    }
    return ( int)( this.lastUse - other.lastUse);
}

< / pride> 除此之外," lastUse"获得分配的时间戳,以微秒和毫秒为单位(是混合的),这给出了一个极好的int溢出溢出

实际问题是:
什么价值观会使此代码崩溃?以便在未来获得正确的测试用例。

使用堆栈跟踪进行更新:

at java.util.ComparableTimSort.mergeHi(Unknown Source)
at java.util.ComparableTimSort.mergeAt(Unknown Source)
at java.util.ComparableTimSort.mergeCollapse(Unknown Source)
at java.util.ComparableTimSort.sort(Unknown Source)
at java.util.ComparableTimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)

3 个答案:

答案 0 :(得分:3)

似乎崩溃是由整数溢出引起的,但不应该是整数溢出。 这被认定为bug,它也为您提供了解决方案。

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7075600

尝试将此作为临时修复:

Adding -Djava.util.Arrays.useLegacyMergeSort=true to my eclipse.ini does seem to have resolved the issue.

您可以在我发布的链接中找到此修补程序。

同时访问此http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6923200,这与第一个链接之前报告的错误类型相同,但由于无法重复创建相同的问题,因此已关闭。

答案 1 :(得分:2)

来自Java SE 7 and JDK 7 Compatibility

区域:API:实用工具

概要:数组和集合的更新排序行为可能会抛出IllegalArgumentException

说明java.util.Arrays.sort和({间接)java.util.Collections.sort使用的排序算法已被替换。如果新排序实现检测到IllegalArgumentException,则可能会抛出Comparable that violates the Comparable contract。以前的实现默默地忽略了这种情况。 如果需要先前的行为,则可以使用新的系统属性java.util.Arrays.useLegacyMergeSort来恢复先前的mergesort行为。 不相容的性质:行为

RFE:6804124

所以正确的实现应该像

  public int compareTo( Symbol other) {
        if( this.lastUse == other.lastUse) {
           return 0;
        } else if( other.lastUse>this.lastUse) {
            return 1;
        }
        return -1;
    }

参考文献

  1. Comparable

答案 2 :(得分:1)

如果不看堆栈跟踪本身就很难分辨。

但是docs提到方法本身可以抛出异常。

  

(可选)如果实现检测到列表元素的自然顺序违反了Comparable合同

<强>更新

看起来好像是因为您的对象无法满足Comparable一致性要求:

  

当且仅当e1.compareTo(e2)== 0与c1的每个e1和e2的e1.equals(e2)具有相同的布尔值时,C类的自然排序被认为与equals一致。请注意,null不是任何类的实例,并且e.compareTo(null)应该抛出NullPointerException,即使e.equals(null)返回false。