如何将Class<? extends Enum<?>>
投射到Class<T>
,<T extends Enum<T>>
?具体来说,我需要将Class<? extends Enum<?>>
的实例传递给Enum.valueOf()
方法。 http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#valueOf(java.lang.Class,%20java.lang.String)
以下是我的课程:
enum Foo1 implements Bar {
VALUE1("A"), VALUE2("B");
String me;
Foo1(String me) {
this.me = me;
}
String getMe() {return me;}
}
enum Foo2 implements Bar {
V1("A"), V2("B");
String me;
Foo2(String me) {
this.me = me;
}
String getMe() {return me;}
}
interface Bar {
String getMe();
}
enum Z {
Z1(Foo1.class), Z2(Foo2.class);
private final Class<? extends Enum<? extends Bar>> myEnum;
Z(Class<? extends Enum<? extends Bar>> myEnum) {
this.myEnum = myEnum;
}
Class<? extends Enum<? extends Bar>> getMyEnum() {
return myEnum;
}
}
class X {
public getMe(Z z, String fooValue) {
Class<? extends Enum<? extends Bar>> fooEnum = z.getMyEnum();
// does not compile
return ((Bar)Enum.valueOf(fooEnum, fooValue)).getMe();
}
}
答案 0 :(得分:0)
这是一种方法
class X {
@SuppressWarnings("unchecked")
public <T extends Enum<T> & Bar> String getMe(Z z, String fooValue) {
Class<T> fooEnum = (Class<T>) z.getMyEnum();
return Enum.valueOf(fooEnum, fooValue).getMe();
}
}
在外部,type参数无用。在内部,它允许我们声明一个既是Enum
又是Bar
的子类型的类型。也不再需要施放到Bar
。
答案 1 :(得分:0)
基于Java目前的通用语法结构,基本上不可能表达您需要的类型关系。所以你可以做一些未经检查的事情,或者,如果您需要的是做
之类的事情String str = someX.getMe(Z1, "VALUE1");
然后你可以抛弃枚举并将Z
声明为带参数的常规类。这样就可以保留一个完整的类型参数,以后可以使用它。
public final class Z<E extends Enum<E> & Bar> {
public static final Z<Foo1> Z1 = new Z<>(Foo1.class);
public static final Z<Foo2> Z2 = new Z<>(Foo2.class);
private final Class<E> myEnumClass;
private Z(Class<E> myEnumClass) {
this.myEnumClass = myEnumClass;
}
public Class<E> getMyEnumClass() {
return myEnumClass;
}
/*
* recreate enum functionality if needed
*/
}
public <E extends Enum<E> & Bar> String getMe(Z<E> z, String fooValue) {
Class<E> fooEnumClass = z.getMyEnumClass();
return Enum.valueOf(fooEnumClass, fooValue).getMe();
}
Enum不是很灵活。有些东西是不能做的,可能不合适。
答案 2 :(得分:0)
执行此操作的简单方法是转换为原始类型Class
:
return ((Bar)Enum.valueOf((Class)fooEnum, fooValue)).getMe();
如果你不喜欢演员表,你可以将你的枚举类包装在另一个类中,当你把它们放在Z中以保留更多的类型关系。
enum Z {
Z1(new Holder<>(Foo1.class)), Z2(new Holder<>(Foo2.class));
private final Holder<?> myEnum;
Z(Holder<?> myEnum) {
this.myEnum = myEnum;
}
Holder<?> getMyEnumHolder() {
return myEnum;
}
static class Holder<T extends Enum<T> & Bar> {
private final Class<T> myEnum;
private Holder(Class<T> myEnum) {
this.myEnum = myEnum;
}
Class<T> getMyEnum() {
return myEnum;
}
}
}
class X {
public static String getMe(Z z, String fooValue) {
return Enum.valueOf(z.getMyEnumHolder().getMyEnum(), fooValue).getMe();
}
}