【问题标题】:Java generics Enum subtyping InterfaceJava泛型枚举子类型接口
【发布时间】:2016-02-12 14:11:55
【问题描述】:

鉴于以下设置:

  public class TestType {

  public static void main(String[] args) {
    List<Constants> list = new ArrayList<>();
    accept(list); //Does not compile
  }

  static void accept(Iterable<MyInterface> values) {
    for (MyInterface value : values) {
      value.doStuff();
    }
  }
}

interface MyInterface<T> {
  T doStuff();
}

enum Constants implements MyInterface<Integer> {
  ONE, TWO, THREE;

  @Override
  public Integer doStuff() {
    return ordinal();
  }
}

为什么编译器不接受列表作为accept()的参数?

List 通过Collection 扩展Iterable,所以这不是问题。

另一方面,编译器告诉我 incompatible types: java.util.List&lt;enums.Constants&gt; cannot be converted to java.lang.Iterable&lt;enums.MyInterface&gt;

但是常量是一个 MyInterface...不是吗?

【问题讨论】:

    标签: java generics types enums


    【解决方案1】:

    问题在于泛型的工作方式。具体来说,泛型是未具体化的......这意味着即使常量是 MyInterface 的子类,编译器也不会将 Iterable&lt;enum.Constants&gt; 视为 Iterable&lt;enum.MyInterface&gt;

    但是,有一种方法可以绕过它:Generic wildcards

    如果您将static void accept(Iterable&lt;MyInterface&gt; values) 更改为static void accept(Iterable&lt;? extends MyInterface&gt; values),它应该工作。

    【讨论】:

    • 确实有效。让我尽快接受答案。非常感谢!
    【解决方案2】:

    您需要使用Iterable&lt;? extends MyInterface&gt; 而不是Iterable&lt;MyInterface&gt;,因为即使ConstantsMyInterface 的子类型,Iterable&lt;Constants&gt; 也不是Iterable&lt;MyInterface&gt; 的子类型 - 我会告诉你原因:

    如果是这样(让我们在下一个示例中使用List 而不是Iterable),我可以这样做:

    List<Constant> constantsList = new ArrayList<Constants>(); // list of constants
    List<MyInterface> ifaceList = constantsList; // you said this would be OK ...
    // assume MyOtherImplementation is another implmentation of MyInterface
    ifaceList.add(new MyOtherImplementation()); // OK, MyOtherImplementation implements MyInterface
    Constant myConst = constantsList.get(0); // Oops! I just got an instance of MyOtherImplementation from List<Constant> - not cool.
    

    【讨论】:

      【解决方案3】:

      泛型类型不会以这种方式继承,尽管乍一看似乎违反直觉。使用Iterable&lt;? extends MyInterface&gt; 将允许您使用任何扩展MyInterface(例如Constants)的类型的Iterable(例如List)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多