33

クラスABCおよびextends D、extends 、 extends があります。BACADA

ArrayListの s があり、それぞれにいくつかの要素があります。

ArrayList<B> b;
ArrayList<? extends A> mix = b;

変数に、またはmix型の要素を含めるつもりでした。タイプの要素を次のように追加しようとしました:BCDCmix

mix.add(anElementOfTypeC);

しかし、IDE ではそうすることができず、次のように表示されます。

anElementOfTypeC は、CAP#1 が新しい型変数である呼び出し変換のメソッドによって CAP#1 に変換できません。CAP#1 は、? のキャプチャから A を拡張します。Aを拡張します

<? extends A>を正しく使用しましたか? どうすればこれを解決できますか?

4

6 に答える 6

44

ArrayList<? extends A>を拡張する未知の型のArrayListを意味しますA
その型はではない可能性があるため、ArrayListにをC追加することはできません。C

実際、ArrayListに何が含まれるべきかわからないため、ArrayListに何も追加できません。

を継承する任意のクラスを保持できるArrayListが必要な場合はA、を使用しArrayList<A>ます。

于 2013-01-13T17:35:01.887 に答える
12

を使用するコレクションに要素を追加することはできません? extends

ArrayList<? extends A>これは、を拡張するArrayListタイプ(正確に1つのAタイプ)であることを意味します。getしたがって、メソッドを呼び出すと、Aであるものが得られることは確かです。しかし、正確に何が含まれているのかわからないため、何かを追加することはできませんArrayList

于 2013-01-13T17:34:38.780 に答える
3

あなたはただ宣言することができます:

ArrayList<A> mix = new ArrayList<A>();

クラスAの任意の要素またはそのサブクラスのいずれかをそのようなリストに追加できます。そのリストから取得すると、で使用可能なメソッドのみを呼び出すことができますA

A「本格的な」クラスであることに限定されないことに注意してください。それは抽象クラスまたはインターフェースでさえあり得ます。

于 2013-01-13T17:34:41.677 に答える
0

この例を見て、要件に応じて選択してください

package com.generic;

import java.util.ArrayList;

public class SuperExtendTest {

    /**
     * @param args
     */
    public static void main(String[] args) {

    }
    public void test() throws Exception {
        ArrayList<Parent> parents=new ArrayList<>();
        parents.add(new Parent());
        parents.add(new Child());
        //parents.add(new GrandParent()); Not allowed

        ArrayList<Parent> p=new ArrayList<>();
        ArrayList<Child> c=new ArrayList<>();
        ArrayList<GrandParent> gp=new ArrayList<>();

        testExtendP(p);
        //testExtendP(c); Not allowed only super type allowed no child
        testExtendP(gp);

        testExtends(c);
        testExtends(p);
        //testExtends(gp); Not allowed because GrantParent does not extends Parent
    }

    /**
     * This Method allowed get operations for Parent 
     * No add 
     * 
     */
    public void testExtends(ArrayList<? extends Parent> list) throws Exception {
    /*  list.add(new Child());
        list.add(new Parent());
        list.add(new GrandParent());
        // can not add
        */
        Child c=(Child) list.get(0);
        Parent parent=list.get(0);
        GrandParent gp=list.get(0);
        /**
         * Unsafe collection way
         */
        ArrayList list2=new ArrayList();
        list.addAll(list2);
    }

    /**
     * This Method allowed add operations for Parent and it's sub types and on get it gives Object type 
     * 
     */
    public void testExtendP(ArrayList<? super Parent> list) throws Exception {
        list.add(new Child());
        list.add(new Parent());
        //list.add(new GrandParent());
        /*can not add because GrandParent can not be converted to Parent type
         * 
         * The method add(capture#3-of ? super Parent) in the type ArrayList<capture#3-of ? super Parent> is not applicable for the arguments (GrandParent)
         * 
         */

        Child c=(Child) list.get(0);
        Parent parent=(Parent) list.get(0);
        GrandParent gp=(GrandParent) list.get(0);
        Object obj=list.get(0);

        /**
         * Unsafe collection way
         */
        ArrayList list2=new ArrayList();
        list.addAll(list2);
    }

    /**
     * This Method allowed all operations for Parent and it's sub types 
     * 
     */
    public void testDirect(ArrayList<Parent> list) throws Exception {
        list.add(new Child());
        list.add(new Parent());
        //list.add(new GrandParent()); 
        /*
         * Can not add GrandParent (Normal generic rule)
         */
    }

}
class GrandParent{

}

class Parent extends GrandParent{

}
class Child extends Parent{

}
于 2014-05-20T12:20:07.183 に答える
0

スーパークラス型の配列リストを作成できます。これを行うことができます。

ArrayList<A> arrayList=new ArrayList<A>();
于 2013-01-13T17:44:58.717 に答える