Я хочу передать любое перечисление значений методу в служебном классе и получить другое перечисление значений того же перечислимого типа. Что-то вроде этого:
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
Я использую Sun JDK 1.6 в любом Eclipse и Знатоке:
$ 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 и сбоях компиляции в Знатоке, какое использование насколько я знаю тот же javac компилятор?
Что случилось с передачей определенных перечислений к дженерику Enum<?>
параметры?
Спасибо,
Martin Schayna
Компилятор Eclipse и javac имеют некоторые различия, особенно когда речь идет о дженериках. Считается, что затмение правильное, но это не имеет значения :)
Попробуйте
public static > Enum getEnumAttribute (Element element, String name,
Enum 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
возвращает Class
, поэтому компилятор не может сказать, какой тип перечисления содержится в массиве enumConstants
.