1. ホーム
  2. java

Javaジェネリックス スーパーキーワード

2023-09-19 21:11:53

質問事項

私はこれらのトピックに目を通しました

しかしながら、私はまだ super というキーワードで迷っているようです。

  1. このようにコレクションを宣言すると

    List<? super Number> list = null;
    list.add(new Integer(0)); // this compiles
    list.add(new Object()); // this doesn't compile
    
    

の親である(型が不明な)いくつかのオブジェクトを含むリストがあります。 Number . つまり Object は適合するはずです (これは Number の親なので)、そして Integer はいけない。その逆がなぜかあるのです。

  1. 次のようなコードがあることを条件とします。

    static void test(List<? super Number> param) {
      param.add(new Integer(2));
    }
    
    public static void main(String[] args) {
      List<String> sList = new ArrayList<String>();
      test(sList);            // will never compile, however...
    }
    
    

上記のコードをコンパイルすることは不可能ですが (そして私の正気は、これが正しい振る舞いであることを示唆しています)、基本的なロジックはその逆を証明することができます。

String is Object, Object is superclass of Number. So String should work.

おかしな話ですが、これが原因で <S super T> の構成を許可しなかった理由ではないでしょうか?もしそうなら、なぜ <? super T> が許可されているのでしょうか?

誰かこのロジックチェーンの欠けている部分を復元するのを手伝ってくれませんか?

どのように解決するのですか?

の bounded ワイルドカードは List<? super Number> を捕捉することができます。 Number とその上位型のいずれかを捕捉することができます。したがって Number extends Object implements Serializable によって捕捉変換可能な唯一の型であることを意味します。 List<? super Number> である。

  • List<Number>
  • List<Object>
  • List<Serializable>

ただし add(Integer.valueOf(0)) を使うことができます。 できない add(new Object())List<Number> または List<Serializable> というのは、一般的な型安全性のルールに違反するからです。

したがって、それは NOT というのは誤りです。 add の任意のスーパータイプは NumberList<? super Number> に変換します。これは、境界付きワイルドカードとキャプチャ変換がどのように動作するかということではありません。を宣言するのではありません。 List<? super Number> を追加したいからです。 Object を追加したいからです (できない!)。 Number オブジェクトを追加したいからです (つまり、このオブジェクトは Number の消費者である)、そして単に List<Number> は制限しすぎです。

参考文献

参照

  • エフェクティブ ジャバ 第2版 項目28:APIの柔軟性を高めるために境界付きワイルドカードを使用する
    • PECS はプロデューサーを意味します。 extends 消費者 super

関連する質問

  • 多すぎてリストアップできない、PECS。 new Integer(0)valueOf など