我想将任何枚举值传递给实用程序类中的方法并获取相同枚举类型的另一个枚举值。像这样的东西:
public class XMLUtils {
public static Enum<?> getEnumAttribute(Element element, String name,
Enum<?> defaultValue) {
if (element.hasAttribute(name)) {
String valueName = element.getAttribute(name);
// search for value
for (Enum<?> value: defaultValue.getClass().getEnumConstants())
if (value.toString().equalsIgnoreCase(valueName))
return value;
}
// not found, return default value
return defaultValue;
}
}
使用方法
getEnumAttribute()
:
// simple enum
public enum EUploadMethod {
INSERT, UPDATE, DELETE
}
// read enum value from XML config file
EUploadMethod method = XMLUtils.getEnumAttribute(element, "method",
EUploadMethod.INSERT);
此代码功能齐全,Eclipse 编译并运行它,没有警告或错误,并且它的工作方式就像一个魅力。
但是当我通过 Maven2 从命令行 清理和编译项目时,它失败并出现错误 ,其中
getEnumAttribute
称为:
$ mvn clean compile
....
[ERROR] /home/.... DataUploader.java:[173,53] inconvertible types
found : java.lang.Enum<capture#414 of ?>
required: .....DataUploader.EUploadMethod
我在 Eclipse 和 Maven 中使用 Sun JDK 1.6:
$ mvn -version
Apache Maven 2.2.1 (r801777; 2009-08-06 21:16:01+0200)
Java version: 1.6.0_14
Java home: /usr/lib/jvm/java-6-sun-1.6.0.14/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux" version: "2.6.27-17-generic" arch: "i386" Family: "unix"
问题:
为什么这段代码在 Eclipse 中是可编译的并且功能,而在 Maven 中编译失败,据我所知使用相同的 javac 编译器?
将特定枚举传递给通用
Enum<?>
参数有什么问题?
Eclipse 编译器和 javac 有一些差异,特别是在泛型方面。人们相信 eclipse 是正确的,但这并不重要:)
尝试
public static <T extends Enum<T>> Enum<T> getEnumAttribute(Element element, String name,
Enum<T> defaultValue) {
...
}
我不知道你使用的是哪个版本的Eclipse,但我认为这里是错误的。 我的版本报告的错误与您在 Maven 中看到的错误相同,这似乎是一个真正的错误。
问题在于
"?"
的签名中有两个通配符 (getEnumAttribute()
),但没有任何约束(也不可能创建一个)强制它们相同。 因此,客户端可以传入一种类型的枚举作为默认值,并获得不同类型的枚举作为返回。
您可以通过用命名类型参数替换两个通配符来消除调用代码中的错误:
class XMLUtils {
@SuppressWarnings("unchecked")
public static <E extends Enum<E>> E getEnumAttribute(Element element, String name,
E defaultValue) {
if (element.hasAttribute(name)) {
String valueName = element.getAttribute(name);
// search for value
for (Enum<?> value: defaultValue.getClass().getEnumConstants())
if (value.toString().equalsIgnoreCase(valueName))
return (E) value;
}
// not found, return default value
return defaultValue;
}
}
但我认为不可能消除未经检查的强制转换,因为
Enum<E>.getClass()
返回 Class<Enum<?>>
所以编译器无法判断 enumConstants
数组中包含什么类型的枚举。