【问题标题】:What's wrong with this Java decorator generic class?这个 Java 装饰器泛型类有什么问题?
【发布时间】:2021-07-09 23:40:20
【问题描述】:

我创建了一个 Java 类来用泛型装饰另一个接口。但是,它总是有一些编译器错误。这是可以重现错误的定制示例代码。

public interface GenericInterface<T> {
  <U, V> GenericInterface<V> testFunc(BiFunction<? super T, ? super U, ? extends V> biFunction);
}

class GenericClass<T> implements GenericInterface<T> {

  private GenericInterface<T> delegate;
  public GenericClass(GenericInterface<T> dele) {
    this.delegate = dele;
  }

  @Override
  public <U, V> GenericInterface<V> testFunc(BiFunction<? super T, ? super U, ? extends V> biFunction) {
    GenericClass<T> impl = new GenericClass<T>(delegate);
    return impl.testFunc((t, u) -> {
      // Do something here ...
      // ...
      // Error for argument u: Required type: capture of ? super U, Provided: Object
      return biFunction.apply(t, u);
    });
  }
}

我尝试了整整一周,无法弄清楚它有什么问题。实际上,我是高级 Java 泛型的新手。

【问题讨论】:

  • 有趣。看起来 Java 只是放弃了类型推断并假设为 Object。我无法猜测为什么。 FWIW 您可以为 lambda (T t, U u) -&gt; { ... } 提供显式类型,它会编译,但这仍然是一个非常好的问题。
  • 很有意思,好像接受T就好了。您也可以将u 转换为U,但是......非常混乱。

标签: java generics decorator


【解决方案1】:

请记住,? 就像一个一次性的新类型变量。

因此,参数的BiFunction 泛型中的? super T 不必与testFunc 调用所要求的? super T 类型相同。

这是可以修复的:

@Override
  public <U, V> GenericInterface<V> testFunc(BiFunction<? super T, ? super U, ? extends V> biFunction) {
    GenericClass<T> impl = new GenericClass<T>(delegate);
   BiFunction<T, U, V> b = (t, u) -> {
    // do something
    return biFunction.apply(t, u);
   };
   return impl.testFunc(b);
  }

【讨论】:

  • 你能解释一下为什么编译器对第一个参数t没有问题,但对第二个u有问题吗?
猜你喜欢
  • 2021-05-10
  • 2020-09-28
  • 2016-11-25
  • 1970-01-01
  • 2011-05-05
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多