1. ホーム
  2. java

[解決済み] なぜJavaのenumリテラルは汎用型パラメータを持つことができないのですか?

2022-04-25 19:36:43

質問

Java の列挙型は素晴らしいです。ジェネリックスもそうです。もちろん、型消去のために後者の限界があることは誰もが知っています。しかし、1つだけ理解できないことがある。なぜ、このような列挙型を作ることができないのか。

public enum MyEnum<T> {
    LITERAL1<String>,
    LITERAL2<Integer>,
    LITERAL3<Object>;
}

この汎用型パラメータ <T> を使えば、いろいろなところで使えるようになります。メソッドへの汎用型パラメータを想像してみてください。

public <T> T getValue(MyEnum<T> param);

あるいはenumクラス自体にも。

public T convert(Object o);

より具体的な例その1

上の例では抽象的すぎると感じる人もいるかもしれないので、なぜこのようなことをしたいのか、より現実的な例を挙げます。この例では

  • Enums。プロパティキーの有限集合を列挙できるから。
  • ジェネリックス:プロパティを格納する際にメソッドレベルの型安全性を確保できるから。
public interface MyProperties {
     public <T> void put(MyEnum<T> key, T value);
     public <T> T get(MyEnum<T> key);
}

より具体的な例その2

データ型の列挙があります。

public interface DataType<T> {}

public enum SQLDataType<T> implements DataType<T> {
    TINYINT<Byte>,
    SMALLINT<Short>,
    INT<Integer>,
    BIGINT<Long>,
    CLOB<String>,
    VARCHAR<String>,
    ...
}

各列挙体リテラルは、当然ながら汎用型に基づく追加のプロパティを持つことになる。 <T> 同時に、enum であること(immutable, singleton, enumerable, などなど)。

質問です。

誰も思いつかなかったのでしょうか?これはコンパイラの制限なのでしょうか?キーワード " 列挙 "は、JVMに生成されたコードを表す構文糖として実装されており、私はこの制限を理解することができません。

どなたか説明してください。答える前に、これを考えてみてください。

  • 汎用型が消されるのは知っている :-)
  • クラスオブジェクトを使用した回避策があることは知っています。それは回避策です。
  • 一般的な型は、コンパイラが生成した型キャストを適用します (例: convert() メソッドを呼び出すとき)。
  • 汎用型 <T> は列挙型になります。したがって、それは enum の各リテラルによって束縛されます。したがって、コンパイラは、以下のような文章を書くときに、どの型を適用すればよいかを知ることができます。 String string = LITERAL1.convert(myObject); Integer integer = LITERAL2.convert(myObject);
  • の総称型パラメータも同様である。 T getvalue() メソッドを使用します。を呼び出すとき、コンパイラは型キャスティングを適用することができます。 String string = someClass.getValue(LITERAL1)

解決方法は?

の時点で議論されています。 JEP-301 拡張列挙型 が、惜しくも撤回されました。JEPで示された例は、まさに私が探していたものです。

enum Argument<X> { // declares generic enum
   STRING<String>(String.class), 
   INTEGER<Integer>(Integer.class), ... ;

   Class<X> clazz;

   Argument(Class<X> clazz) { this.clazz = clazz; }

   Class<X> getClazz() { return clazz; }
}

Class<String> cs = Argument.STRING.getClazz(); //uses sharper typing of enum constant

しかし、残念ながら、JEPは重大な問題に直面しており、解決することができませんでした。 http://mail.openjdk.java.net/pipermail/amber-spec-experts/2017-May/000041.html