16

Comparable を実装しない任意のクラスを作成し、それをツリーセットとして使用しようとすると、実行時にオブジェクトが挿入されたときに例外がスローされます。

public class Foo {
}

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

私は Java の専門家ではありませんが、これについては、予期していなかった方法で動的に型付けされているように見えました (ala Python)。TreeSet の実装で、ジェネリック型引数が Comparable を実装する必要があることを指定して、コンパイル時にキャッチできるようにする方法はありませんか? 非ジェネリック関数は、引数としてインターフェイスを取ることができます。ジェネリックでも同じことはできませんか?

4

1 に答える 1

32

TreeSet代わりに を提供できるため、そのように実装されます。Comparatorこの場合、要素は である必要はありませんComparable。実装を複数のクラスに分割せずに両方の動作をサポートする唯一の方法は、ランタイム チェックを含めることでした。これは、単にそのクラスの作成者による設計上の決定でした。

パブリック コンストラクターの代わりにファクトリ メソッドをTreeSet公開することは、より厳密なジェネリック型の制約を使用してコンパイル時のチェックを維持する方法でしたが、それは、引数なしのパブリック コンストラクターとコピー コンストラクターを公開するというコア コレクション API の規則からの脱却でした。実装クラス。あなたのコメントで指摘したように、グアバはそのコレクションで工場のルートをたどり、私見はそれの方が適しています.

于 2012-12-15T08:19:07.023 に答える