6

以下代码在 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();
    }
}

但是,直接使用 (JDK 7) 或通过 Maven 编译javac失败并出现以下错误:

type argument ? extends T is not within bounds of type-variable E

老实说,枚举 + 接口 + 类型参数(泛型)的复杂性一下子让我在编写代码时感到厌烦,但我认为我终于做对了。

目标是编写如下调用代码:

Cloneable something = enumTest.getOne(Cloneables.class);

例如,在 Eclipse 中,以下测试编译并通过:

@Test
public void testGetFirst() {
    assertSame(Cloneables.One, getOne(Cloneables.class));
}

任何关于哪个是“正确的”、Eclipse 或 javac 的线索都值得赞赏。

还赞赏有关实现该想法的替代方法的任何建议:将类作为方法参数,可以在其中使用EnumSet.allOf()并且还确定 Enum 对象的类型EnumSet

顺便说一句,不要费心批评这种方法的目的;我已经从更有用/更有意义的代码中减少了它。我对讨论“从枚举类型中查找第一个元素”的优点不感兴趣——这不是这个问题的重点。

4

1 回答 1

3

您需要确保它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();
}
于 2014-12-31T22:45:34.173 回答