4

ArrayList APIでは、 add()はジェネリック パラメータ タイプの引数を取りますが、contains()indexOf()はObject型の引数を取ります。

public class ArrayList<E> ...{
     public boolean add(E e);  
     public boolean contains(Object o);
     public int indexOf(Object o);
     ....
}

ArrayList の Java ドキュメント

だから、ジェネリックと関係があるのか​​ 、それともデザインの一貫性がないのか 疑問に思っていますか?

私はOpenjdk の実装を見ましたが、これに関する具体的な理由は見つかりませんでした。

4

2 に答える 2

10

APIが言っていることは次のとおりです。

  1. add();以外は何もできませんE
  2. ただし、そうでないものを検索することはできますE(ただし、 のインスタンスと等しい可能性がありますE)。

次の例を検討してください。

public class Main {
    public static class Key {
        private final int k;
        public Key(int k) {
            this.k = k;
        }
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Key)) {
                return false;
            }
            Key rhs = (Key)obj;
            return k == rhs.k;
        }
        @Override
        public int hashCode() {
            //...
            return 0;
        }
    }
    public static class Data extends Key {
        private final int d;
        public Data(int k, int d) {
            super(k);
            this.d = d;
        }
    }
    public static void main(String[] args) {
        List<Data> l = new ArrayList<Data>();
        l.add(new Data(123, 456));
        l.add(new Data(42, 24));
        System.out.println(l.contains(new Key(789)));
        System.out.println(l.contains(new Key(123)));
        System.out.println(l.contains(new Key(42)));
    }
}

最後の 3 行はcontains()、取得に制限されている場合はコンパイルされませんData

于 2013-01-23T16:39:49.937 に答える
3

ここに良い説明があります: Set.contains() が E ではなく Object を取るのはなぜですか?

于 2013-01-23T16:55:27.467 に答える