为什么Java枚举文字不能具有泛型类型参数?
Java枚举是伟大的。 泛型也是如此。 当然,由于类型擦除,我们都知道后者的局限性。 但有一件事我不明白,为什么我不能创建这样的枚举:
public enum MyEnum<T> {
LITERAL1<String>,
LITERAL2<Integer>,
LITERAL3<Object>;
}
这个泛型类型参数<T>
反过来可以在各个地方有用。 设想一个方法的泛型类型参数:
public <T> T getValue(MyEnum<T> param);
或者甚至在枚举类本身:
public T convert(Object o);
更具体的例子#1
由于上面的例子对某些人来说可能看起来太抽象了,下面是我为什么要这样做的一个更真实的例子。 在这个例子中,我想使用
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 ”被实现为语法糖,代表JVM生成的代码,我不理解这个限制。
谁可以向我解释这一点? 在你回答之前,考虑一下:
String string = LITERAL1.convert(myObject); Integer integer = LITERAL2.convert(myObject);
时应用的类型String string = LITERAL1.convert(myObject); Integer integer = LITERAL2.convert(myObject);
String string = LITERAL1.convert(myObject); Integer integer = LITERAL2.convert(myObject);
T getvalue()
方法中的泛型类型参数。 编译器可以在调用String string = someClass.getValue(LITERAL1)
时应用类型转换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
问题的答案是:
由于类型擦除
这两种方法都不可能,因为参数类型被擦除。
public <T> T getValue(MyEnum<T> param);
public T convert(Object);
为了实现这些方法,你可以构造你的枚举为:
public enum MyEnum {
LITERAL1(String.class),
LITERAL2(Integer.class),
LITERAL3(Object.class);
private Class<?> clazz;
private MyEnum(Class<?> clazz) {
this.clazz = clazz;
}
...
}
因为你不能。 认真。 这可以添加到语言规范。 它没有。 这会增加一些复杂性。 这对成本的好处意味着它不是高优先级。
更新:当前正在添加到JEP 301:增强型枚举下的语言。
链接地址: http://www.djcxy.com/p/57843.html上一篇: Why shouldn't Java enum literals be able to have generic type parameters?