4

Java7でCollections.sort()を使用して(明らかに悪名高い)IllegalArgumentExceptionに見舞われました。SO
のおかげで、基本的に(咳の)貧弱なコードが原因を理解しています。
問題は、私は例外を自分で再現することはできないということです。私はいくつかのjdkソースコードを掘り下げて、どのクラスがその例外をスローしているかを見つけました。アイデアは、それに応じたテストケースを作成することです。

ちなみに、ここにコードがあります
<pride level = "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)
4

3 に答える 3

3

クラッシュは整数のオーバーフローが原因のようですが、想定外でした。これはバグとして識別され、ウォークアラウンドも提供します。

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、これは最初のリンクの前に報告されたのと同じ種類のバグでしたが、同じ問題を繰り返し作成できなかったため、閉じられました。

于 2012-10-23T22:05:44.160 に答える
2

JavaSE7およびJDK7の互換性から

エリア: API:ユーティリティ

概要:配列とコレクションの更新された並べ替え動作により、IllegalArgumentExceptionがスローされる場合があります

説明:java.util.Arrays.sortおよび(間接的に)によって使用される並べ替えアルゴリズムjava.util.Collections.sortは置き換えられました。IllegalArgumentException新しいソート実装は、を検出した場合にをスローする可能性がありComparable that violates the Comparable contractます。以前の実装では、このような状況を黙って無視していました。以前の動作が必要な場合は、新しいシステムプロパティ、、を使用して、java.util.Arrays.useLegacyMergeSort以前のマージソート動作を復元できます。非互換性の性質:行動

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. 同程度の
于 2012-10-23T21:51:50.750 に答える
1

スタックトレース自体を見ずに見分けるのは難しい。

しかし、ドキュメントには、メソッド自体が例外をスローする可能性があると記載されています。

(オプション)リスト要素の自然な順序がComparableコントラクトに違反していることが実装で検出された場合

アップデート

Comparableオブジェクトが整合性要件を満たしていないため、次のようになります。

クラスCの自然な順序は、e1.compareTo(e2)== 0がクラスCのすべてのe1およびe2に対してe1.equals(e2)と同じブール値を持つ場合にのみ、equalsと一致すると言われます。 nullはどのクラスのインスタンスでもないため、e.equals(null)がfalseを返しても、e.compareTo(null)はNullPointerExceptionをスローする必要があります。

于 2012-10-23T21:44:48.923 に答える