今天一位同事遇到了一个有趣的问题,虽然我认为实际的,大局的答案是“我们遇到这个问题意味着我们做错了什么”,我想我会无论如何都要问这个。
鉴于以下内容:
public class CrazyEnumTest {
public class EnumeratedThing<T extends Enum<T>> {
public T myValue;
public EnumeratedThing(T value) {
myValue = value;
}
}
public static void main (String[] args) {
String className = args[0];
String enumValue = args[1];
Enum<?> value1 = Enum.valueOf(Class.forName(className), enumValue);
EnumeratedThing<?> thing1 = new EnumeratedThing(value1);
}
}
在调用Enum.valueOf时出现以下编译错误:
Bound mismatch: The generic method valueOf(Class<T>, String) of type Enum<E> is not applicable for the arguments (Class<capture#1-of ?>, String). The inferred type capture#1-of ? is not a valid substitute for the bounded parameter <T extends Enum<T>>
所以,我的问题是:如果只给出枚举类型名称的String表示形式以及其中一个值的.name(),是否可以获得对相应枚举类型对象的引用作为枚举?
答案 0 :(得分:9)
编译错误告诉您Class<?>
与Class<? extends Enum>
不同。尝试:
Enum<?> value1 =
Enum.valueOf((Class<? extends Enum>) Class.forName(className), enumValue);
请注意,您将获得未经检查的强制转换警告,因此请确保className
实际上代表枚举。您可以通过调用Class
对象上的isEnum()
方法进行检查,如下所示:
Class<?> enumClass = Class.forName(className);
if (enumClass.isEnum()) {
@SuppressWarnings("unchecked") // we just checked it, so it had better work
Enum<?> value1 = Enum.valueOf((Class<? extends Enum>) enumClass, enumValue);
EnumeratedThing<?> thing1 = new EnumeratedThing(value1);
}
当然,无论如何,你都会在“new EnumeratedThing(value1)
”上收到原始类型警告。
答案 1 :(得分:1)
在调用方法之前,只需转换您创建的类, 这样它符合方法签名:
Class<?> c = Class.forName(className);
Class<? extends Enum> ce = (Class<? extends Enum>)c;
Enum<?> value1 = Enum.valueOf(ce, enumValue);
现在该类被视为Enum的子类。
备注: