java - 对类型参数做出假设?

标签 java generics

我想将 Iterator 子类化为 FooIterator。我的代码看起来像这样:

public class FooIterator<E> implements Iterator<E> {
  public FooIterator(Collection<Bar> bars) {
    innerIterator = bars.iterator();
  }

  @Override
  public boolean hasNext() {
    return innerIterator.hasNext();
  }

  @SuppressWarnings("unchecked")
  @Override
  public E next() {
    Bar bar = innerIterator.next();
    return new E(bar);
  }

  @Override
  public void remove() {
    throw new UnsupportedOperationException("Don't remove from FooIterator!");
  }

  private Iterator<Bar> innerIterator;
}

...除了,当然,这是行不通的,因为我无法从 Bar 实例化一个新的 E。

我只会将其与具有采用 Bar 的构造函数的 E 一起使用。有什么方法可以向编译器“证明”这一点,或者如果 E 没有合适的构造函数就抛出运行时错误?

或许我只是没有在这里使用正确的设计模式?我最近一直在做很多 C++,我觉得我可能以错误的方式处理这个问题。

最佳答案

这是一种有点复杂的方法,但它可以工作并且类型安全(使用反射的解决方案不会)。它基本上包括将 E 的构造从 Bar 委托(delegate)给一个单独的类。你可以有一个 BarConverter 接口(interface):

interface BarConverter<E> {
    E convert (Bar bar);
}

那么你的类可以变成:

public class FooIterator<E> implements Iterator<E> {

    public FooIterator(Collection<Bar> bars, BarConverter<E> converter) {
        innerIterator = bars.iterator();
        this.converter = converter;
    }

    @Override
    public E next() {
        Bar bar = innerIterator.next();
        return converter(bar);
    }
}

关于java - 对类型参数做出假设?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18115127/

相关文章:

java - 为什么我们需要有界通配符 <?在 Collections.max() 方法中扩展 T>

来自模板化对象的 Java 8 功能构造函数

generics - Dart 。使用通用T和对象有什么区别?

java - 关于契约使用的概念性问题

java - 即使在成功加载所需的目标文件后,在加载 JNI 依赖项时也会在 Java 中获取 UnsatisfiedLinkError( undefined symbol )

java - 本地化异常(在 Struts2 应用程序内)

generics - Java8 : compiler error with generic version in lambda function

java - 在java中获取排序数组的原始索引(Android)

java - 将方法从 mainActivity 移动到类文件

c# - 为什么 new() 约束必须需要公共(public)构造函数?