【问题标题】:Discrepancy between Eclipse compiler and javac - Enums, interfaces, and genericsEclipse 编译器和 javac 之间的差异 - 枚举、接口和泛型
【发布时间】:2015-02-27 21:18:49
【问题描述】:

以下代码在 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 编译失败并出现以下错误:

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() 中使用,并且还确定 EnumSet 中的 Enum 对象的类型

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

【问题讨论】:

标签: java eclipse enums enumset


【解决方案1】:

您需要确保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();
}

【讨论】:

  • 我什至不知道你可以在声明这样的类型参数时应用&amp; 运算符。即使在编写 Java 代码将近 18 年后,我今天也学到了一些新东西!
  • 顺便说一句,我使用Class 的原始形式的原因是,如果没有T 扩展Enum,Eclipse 编译器将不会接受Class 类型参数的任何值。因此,使用它原始是不知道将CloneableEnum 组合为T 的副作用。
  • 有趣的是,Eclipse 不会让我将集合声明为 EnumSet&lt;T&gt; - 它抱怨 “绑定不匹配:类型 T 不是有界参数的有效替代品 > 类型为 EnumSet"。幸运的是,EnumSet&lt;? extends T? 有效并且是等效的。
  • @E-Riz:不;实际上,界限应该是T extends Enum&lt;T&gt; &amp; Cloneable。然后,您可以再次删除通配符。
  • @E-Riz 鉴于泛型是在 2004 年添加到 Java 中的,您只有 10 年(几乎 11 年)来了解它们 :-)。我发现泛型是迄今为止 Java 中最复杂的领域。使用它们并没有那么糟糕,但是在声明任何泛型方法/类时,它可能会非常艰巨。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-30
  • 1970-01-01
  • 2012-01-09
  • 1970-01-01
  • 2011-02-20
相关资源
最近更新 更多