1

SortedSetがインターフェイスであり、具体的なクラスではないにもかかわらず、このコードが正常にコンパイルおよび実行される理由を誰かが説明できますか?

public static void main(String[] args) {

    Integer[] nums = {4, 7, 8, 14, 45, 33};

    List<Integer> numList = Arrays.asList(nums);
    TreeSet<Integer> numSet = new TreeSet<Integer>();
    numSet.addAll(numList);

    SortedSet<Integer> sSet = numSet.subSet(5, 20);
    sSet.add(17);
    System.out.println(sSet);

}

通常、結果を出力します。[7, 8, 14, 17]

さらに、SortedSetを(予想どおりに)インスタンス化できないという事実によって、私の不思議が高まります。この行はコンパイルされません:

SortedSet<Integer> sSet = new SortedSet<Integer>();

ただし、コードを試してみると、次のようになります。

public static void main(String[] args) {

    Integer[] nums = {4, 7, 8, 14, 45, 33};

    List<Integer> numList = Arrays.asList(nums);
    numList.add(56);

    System.out.println(numList);
}

をスローしUnsupportedOperationExceptionます。これは、Listがインターフェースであり、具体的なクラスとして扱うことができないという事実から来ていると思います。何が本当SortedSetですか?

4

4 に答える 4

3

SortedSetはインターフェースです。これは、このインターフェースを実装するクラスへの参照を持つことはできますが、暗黙化なしでクラスのインスタンスを作成することはできないことを意味します。

Arrays.asList()の場合、元の配列をラップするクラスを返します。元の配列に追加できないため、追加はサポートされていません。たとえば、setを使用する場合は、元の配列を変更します。

于 2012-12-16T10:54:45.657 に答える
1
List<Integer> numList = Arrays.asList(nums);

Array.asList()配列を返し ますが、リストインターフェイスでラップします。したがって、リストは引き続き配列に支えられており、配列は固定サイズであるため、配列に要素を追加/削除することはできません。そのため、次の行で例外がスローされますUnsupportedOperationException

詳細については、javaArrayListはまだ配列の背後にありますが、要素を削除/追加するためのヘルパーメソッドがいくつかあります(resizeable array詳細については、フレーズをwikiで確認できます。

第二にSortedSet、インターフェースです。抽象クラスのようなインターフェースは、それを実装/拡張するクラスへの参照を持つことができますが、それは具象クラスではないため、それら(インターフェースまたは抽象クラス)上にオブジェクトを作成することはできません。

そして、私はあなたが尋ねる2つの質問の両方が、おそらくpolymorphismOOPに関連しているので、このフレーズもwikiすることをお勧めします。

この助けを願っています:)

于 2012-12-16T10:55:57.793 に答える
0

私が正しく理解していれば、オブジェクトをSortedSet(または任意のインターフェイスタイプ)として正常に参照できる理由を尋ねています。変数の型がインターフェースまたは抽象クラスである場合、それは、変数がその変数の型を継承するオブジェクト(またはnullオブジェクト)を保持している必要があることを意味します。

すべてのオブジェクトの実際の型は具象クラスである必要がありますが、sSet変数は、SortedSetを継承(実装)するクラスのインスタンスを保持するためにのみ必要です。

メソッドの場合、TreeSet.subSetSortedSetを実装する内部定義の具象クラスを型とするオブジェクトを返します。

于 2012-12-16T14:20:01.723 に答える
0

SortedSetは、クラスではなくインターフェイスです。

非抽象クラスからのみインスタンス化できます。

リストもインターフェースです。しかし、Listのドキュメントによると、メソッド「add」はオプションです。つまり、サポートされる保証はありません。

オプションのメソッドは、インターフェースの考え方や契約と矛盾していると思います。NonModifyableList(追加なし)とModifyableList(追加あり)がある方が良いでしょう。現在の悪い選択は、おそらく歴史と古いコードを壊したくないという願望の結果です。

于 2012-12-16T10:53:15.857 に答える