9

ジェネリック インターフェイスがあるとします。

public interface MyInterface<T> {
    T doSomething();
}

を実装する列挙型を宣言することは可能ですMyInterface<T>が、すべての列挙型定数が異なる値に対してそれを実装しTますか? つまり、次の列挙型が与えられます。

public enum MyEnum {
    FOO,
    BAR,
    BAZ;
}

FOOimplements MyInterface<Integer>BARimplements MyInterface<String>BAZimplementsに変更して、全体がimplementsMyInterface<List<MyOtherType>>になるようにすることはできますか? これをそのまま実行することは完全に実行可能であるように思われるため、タイプセーフな方法で実行できる可能性があります。MyEnumMyInterface<?>

4

2 に答える 2

12

いいえ、amalloyが指摘したように、Javaでは列挙型を型パラメーターで宣言することはできません。列挙型がどのように使用されるかを考えると、たとえば、である理由が明らかになりますswitch

また、言語がジェネリック列挙型をどのように実装するかを検討してください。これは簡単なことではありません。ジェネリック列挙型の場合MyEnum<T>、各列挙型定数はT特定のタイプに解決する必要があります。そうしないと、定数にはなりません。このことを考慮:

enum MyEnum<T> {
    FOO; // T is not resolved
}

ここは何Tですか?FOO言語は、それを表現できるようにするためだけに新しい構文を必要とします。次に例を示します。

enum MyEnum<T> {
    FOO<String>;
}

そのため、過度に説得力のあるユースケースを持たないセマンティクスをサポートするために、言語の複雑さが増しています。言語設計者が列挙型の型パラメーターを単純に修正した理由は簡単に理解できます。

回避策:

列挙型を使用しないだけで、目的のパターンをエミュレートできます。インターフェイスの実装をユーティリティクラスに整理します。

public class MyImplementations {

    public static final MyInterface<Integer> FOO =
            new MyInterface<Integer>() {
                ...
            };

    public static final MyInterface<String> BAR =
            new MyInterface<String>() {
                ...
            };

    public static final MyInterface<List<MyOtherType>> BAZ =
            new MyInterface<List<MyOtherType>>() {
                ...
            };

    private MyImplementations() { }
}

本質的に欠落している唯一のことは、さまざまな実装を反復する方法です。これは、で行うことができたようにですがMyEnum.values()、仮想的MyEnum<T>には、反復できる最も具体的なタイプはですMyEnum<?>

于 2012-11-04T00:25:06.230 に答える
4

いいえ、そのようなクラスをどのように使用できますか?

MyEnum x = whatever;
x.foo().get(0); // how can javac know that x is the version that gives back a List?
于 2012-11-03T07:32:23.033 に答える