[英]Interesting generics-related discrepancy between javac and Eclipse IDE compiler
[英]Discrepancy between Eclipse compiler and javac - Enums, interfaces, and generics
以下代码在Eclipse中编译(并按预期运行测试):
import java.util.EnumSet;
public class EnumTest {
static enum Cloneables implements Cloneable {
One, Two, Three;
}
public <T extends Cloneable> T getOne(Class enumType) {
EnumSet<? extends T> set = EnumSet.allOf(enumType);
return set.iterator().next();
}
}
但是,直接使用javac
(JDK 7)或通过Maven进行javac
失败,并出现以下错误:
type argument ? extends T is not within bounds of type-variable E
说实话,enums +接口+类型参数(泛型)的复杂性一下子就把我扔掉了,就像我编写代码一样,但我觉得我终于把它弄好了。
目标是编写这样的调用代码:
Cloneable something = enumTest.getOne(Cloneables.class);
例如,在Eclipse中,以下测试编译并传递:
@Test
public void testGetFirst() {
assertSame(Cloneables.One, getOne(Cloneables.class));
}
任何有关“正确”,Eclipse或javac的线索都值得赞赏。
还要了解有关实现该想法的替代方法的任何建议:将类作为可以在EnumSet.allOf()
使用的方法参数,并且还确定EnumSet
的Enum对象的类型
顺便说一下,不要打扰批评这种方法的目的; 我已经从更有用/有意义的代码中减少了它。 我对讨论“从枚举类型中找到第一个元素”的优点不感兴趣 - 这不是这个问题的重点。
您需要确保T
是枚举类型,否则它将不符合EnumSet
的约束:
public <T extends Enum<T> & Cloneable> T getOne(Class enumType)
此外,您不需要EnumSet
的通配符,也不应使用原始Class
类型:
public <T extends Enum<T> & Cloneable> T getOne(Class<T> enumType) {
EnumSet<T> set = EnumSet.allOf(enumType);
return set.iterator().next();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.