4

多くの検索の結果、通常のクラスに関連する質問がたくさん見つかりましたが、列挙型に実際に関連する質問はありません。

これは正常に機能します。

package list;

public interface Testing { 
    //treat as a tag interface.
}
package list;

public class Foo implements Testing {
}
package list;

import java.util.ArrayList;
import java.util.List;

public class Bar {
    public Bar(){
        List<Foo> myList = new ArrayList<Foo>();
        myList.add(new Foo());
        testList(myList);
        testMethod(new Foo());
    }

    public void testMethod(Testing myInstance){
        //do nothing
    }

    public <Testing> void testList(List<Testing> myList){
        //do nothing
    }
}

Enums しかし、私の問題は、代わりに 同じことをしようとするとどうなるかを理解することにあります Foo

ここでの例は、インターフェイスパラメータを受け入れるように定義されたインターフェイス定義があります。これは、実際には、インターフェイスを実装する列挙型によって実装されます。

私は2つのインターフェースを持っています:

public interface MyEnumInterface {
  //implemented by Enums
}
import java.util.List;

public interface SecondInterface {
    public MyEnumInterface testMe(String myString);
    public <MyEnumInterface> List<MyEnumInterface> testingList();
    public List <MyEnumInterface> enumTestOne(String anotherString);
    public List <MyEnumInterface> enumTestTwo(String anotherString);
}

次の2つのエマム:

public enum MyEnum implements MyEnumInterface{
    VALUE_ONE,
    VALUE_TWO,
    VALUE_THREE;
}
public enum MyEnum2 implements MyEnumInterface{
    VALUE_A,
}

そして、テストJavaクラス:

import java.util.ArrayList;
import java.util.List;

class MyClass implements SecondInterface{

    public MyClass(){
        single(testMe(""));
        enumTestOne("");
        enumTestTwo("");
    }
    public MyEnum testMe(String someParam){
            return MyEnum.VALUE_ONE;
    }

    public List<MyEnumInterface> enumTestOne(String anotherString) {
        List<MyEnum> returnL = new ArrayList<MyEnum>();
        returnL.add(MyEnum.VALUE_ONE);
        returnL.add(MyEnum.VALUE_THREE);
        return returnL;
    }

    public List<MyEnumInterface> enumTestTwo(String anotherString) {
        List<MyEnum2> returnL = new ArrayList<MyEnum2>();
        returnL.add(MyEnum2.VALUE_A);
        return returnL;
    }


    public List<MyEnum> testingList(){
        List<MyEnum> returnL = new ArrayList<MyEnum>();
        returnL.add(MyEnum.VALUE_ONE);
        returnL.add(MyEnum.VALUE_THREE);
        return returnL;
    }


    public void single(MyEnumInterface val){
        System.out.println("Value is " + val);
    }


    public static void main(String[] args){
        MyClass clazz = new MyClass();
    }
}

enumTestOne(..)の戻り型がリストとしてコード化されているが、インターフェースがリストを指定しているという問題と戦っています。列挙型'MyEnum'の個々のインスタンスの場合は正常に機能しますが、値のリストの場合は次のように失敗するようです。

「エラー:クラスMyClassのメソッドリストを特定の型に適用できません。必須:リストが見つかりました:リストの理由:実際の引数リストをメソッド呼び出し変換でリストに変換できません。」

これを回避する方法がわかりません-上記の宣言を追加して読み取れるようにしました public <MyEnumInterface> List<MyEnumInterface> testingList(); が、失敗し続けている間、チェックされていないキャストについての「警告」が表示されます

これはすべて、ジェネリックスとそれらが列挙型とどのように関連しているかについての私の深い理解の欠如に起因します。

私はに関していくつかの興味深い宣言を見てきました <? extends Enum<E> & SecondInterface> が、それは私の理解を広げます。助けてください!

余談ですが、戻りクラスの前の一般的な宣言は、型の侵食の目的で「T」を指定するために使用されると考えるのは正しいですか?

4

2 に答える 2

4

ジェネリックはinvariant自然界にあります。したがってList<String>、のサブタイプではありませんList<Object>

MyEnumInterface個別の列挙型クラスではなく、リストを含めるようにメソッドを変更する必要があります。

public List<MyEnumInterface> enumTestOne(String anotherString) {
    List<MyEnumInterface> returnL = new ArrayList<MyEnumInterface>();//Change
    returnL.add(MyEnum.VALUE_ONE);
    returnL.add(MyEnum.VALUE_THREE);
    return returnL;
}

public List<MyEnumInterface> enumTestTwo(String anotherString) {
    List<MyEnumInterface> returnL = new ArrayList<MyEnumInterface>();//Change
    returnL.add(MyEnum2.VALUE_A);
    return returnL;
}
于 2012-09-06T19:03:32.233 に答える
2

実装クラスが使用する実装を定義できるようにする場合MyEnumInterfaceは、インターフェイスメソッドの戻り型をList任意ののとして指定できますMyEnumInterface

public List<? extends MyEnumInterface> enumTestOne(String anotherString);
public List<? extends MyEnumInterface> enumTestTwo(String anotherString);

これらのメソッドの実装により、具体的なリターンタイプを定義できます。

public List<MyEnum> enumTestOne(String anotherString) {
    List<MyEnum> returnL = new ArrayList<MyEnum>();
    returnL.add(MyEnum.VALUE_ONE);
    returnL.add(MyEnum.VALUE_THREE);
    return returnL;
}

public List<MyEnum2> enumTestTwo(String anotherString) {
    List<MyEnum2> returnL = new ArrayList<MyEnum2>();
    returnL.add(MyEnum2.VALUE_A);
    return returnL;
}

ちなみに、「リバース」でも同じことができますsuper。これは、指定されたタイプのスーパータイプである任意のタイプを使用できることを指定します。

public void addToList(List<? super MyEnum> list) {
    list.add(MyEnum.VALUE_ONE);
}

addToList(new ArrayList<MyEnum>());
addToList(new ArrayList<MyEnumInterface>());

も参照してください

Java Generics(ワイルドカード)

なぜSomeClassはJavaジェネリック型のSomeClassと同等ではないのですか?

于 2012-09-06T19:48:56.090 に答える