代码之家  ›  专栏  ›  技术社区  ›  EarthTurtle

通配符绑定内的泛型类型出错

  •  1
  • EarthTurtle  · 技术社区  · 11 月前

    我有一个自定义迭代器接口

    public interface ThrowingIterator<T, E extends Throwable> {
      // matches interface of standard Iterator, but next() and hasNext() can throw E
    }
    

    和一个实现

    public class CustomIterator implements ThrowingIterator<List<MyType>, IOException> {
      // ...
      public CustomIterator() {
         // ...
      }
      public static ThrowingIterator<List<MyType>, IOException> helperFactory() {
        // ...
      }
    }
    

    哪里 class MyType implements MyInterface 。我的问题属于以下职能范围:

    ThrowingIterator<List<? extends MyInterface>, IOException> getIterator() {
      if (someCondition) {
        return new CustomIterator();
      }
      return CustomIterator.helperFactory();
    }
    

    由于不同的原因,编译器在两个返回语句上都出现错误。Intellij提供以下功能:

    // first
    Required: ThrowingIterator<List<? extends MyInterface>, IOException>
    Provided: CustomIterator
    // second
    Required: ThrowingIterator<List<? extends MyInterface>, IOException>
    Provided: ThrowingIterator<List<MyType>, IOException>
    

    据我所知, CustomIterator 应该符合需要,因为它实现的类型 ThrowingIterator 符合通配符范围(尤其是第二种情况,因为 MyType implements MyInterface ,这正是我所想的 ? extends MyInterface 正在尝试捕获。) 如何在最大限度地减少声明/签名中的通配符数量的同时解决此泛型问题? 的签名 getIterator() 我也明白在列表上提供迭代器是不好的做法;修复在其他地方处理的问题。

    1 回复  |  直到 11 月前
        1
  •  4
  •   rgettman    11 月前

    你的方法 getIterator 不编译,因为默认情况下Java的泛型是不变的。

    这意味着即使 List<MyType> 是的子类型 List<? extends MyInterface> ThrowingIterator<List<MyType>, IOException> 的一个亚型 ThrowingIterator<List<? extends MyInterface>, IOException> .

    这与 列表<我的类型> 不是的子类型 List<MyInterface> -Java的泛型是不变的。你已经通过添加 ? extends ,导致 列出<?扩展MyInterface> 。现在你只需要再做一次,因为你添加了另一层仍然不变的泛型。

    添加 ? 延伸 再一次

    //               vvvvvvvvv
    ThrowingIterator<? extends List<? extends MyInterface>, IOException> 
        getIterator() {
    

    这将满足IntelliJ和Java编译器的要求。