[解決済み] なぜ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
関連
-
エラー java.util.NoSuchElementException
-
スレッド "main "での例外をEclipseで解決 java.lang.Error: 未解決のコンパイル問題、コンパイラとパッケージの不整合
-
myeclipseでコンパイルするとAntエラーが発生する javaの例外が発生しました。
-
javaで非静的な解を静的な参照にすることができない
-
javaでよく使われる英単語
-
[解決済み] なぜJavaにはtransientフィールドがあるのですか?
-
[解決済み] メソッドの戻り値の型を汎用的にするにはどうすればよいですか?
-
[解決済み] C#でジェネリックメソッドからNULLを返すにはどうしたらいいですか?
-
[解決済み] GsonでList<T>オブジェクトをデシリアライズする?
-
[解決済み] Java enumとpublic static finalフィールドを持つクラスとでは、どのような利点がありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
javaで非静的な解を静的な参照にすることができない
-
eclipseにプロジェクトをインポートした後、Editorにmain typeが含まれない問題
-
Eclipseでプロジェクトエクスプローラービューとパッケージエクスプローラービューを使う
-
Java コンパイルエラー - スレッド "main" で例外 java.lang.Error: 未解決のコンパイル問題です。
-
spring aop アドバイスからの Null 戻り値が、サマリーのプリミティブ戻り値と一致しない。
-
起動時にEclipseエラーが発生しました。起動中に内部エラーが発生しました。java.lang.NullPoin: "Javaツーリングの初期化 "中に内部エラーが発生しました。
-
java 例外。Javaツールの初期化
-
IDEA パッケージステートメントの欠落
-
java -serverコマンドで「Error: no `server' JVM at ... jvm.dll」を解決する方法です。
-
テストが見つかりませんでした