我在库中有一个接口,看起来像这样:

public interface Sender<T> {

  String send(T parameters);
}


这是一个库,所以我更喜欢一个无需更改的解决方案。
现在,有几个类可以实现此接口。每个类都以T扩展Class ParamsVal的方式实现它。

现在,我想实现一个队列,在其中可以保存适合参数的数据,并在确定的时间内调用send()(我需要返回值String,因此不能简单地使用Runnable和线程) 。

因此,我创建了一个像这样的类:

public class MessageEntry{
  private ParamsVal messageParameters;
  private Sender<? extends ParamsVal> sender;


  public MessageEntry(ParamsVal messageParameters, Sender<? extends ParamsVal> sender) {
      this.messageParameters = messageParameters;
      this.sender = sender;
  }

  public String send(){
      return this.sender.send(this.messageParameters);
  }
}


与send()的return线我得到错误

 send(capture<? extends ParamsVal>) in Sender cannot be applied to (ParamsVal)


有什么想法,如何解决呢?

编辑:修复了次要copycodeerror

最佳答案

当您不了解通用通配符问题时,最简单且通常最好的方法是删除通配符。

因此,正如其他人建议的那样,请改用Sender<ParamsVal> sender

现在,关于正在发生的事情以及您想做的尽可能灵活的选择可以做什么。

Sender<ParamsVal>的意思是“发送ParamsVal对象的发件人”。

Sender<? extends ParamsVal>的意思是“发件人。我不知道它发送的是什么。但是我确实知道,无论发送什么,它都是ParamsVal的子类型,或者可能是ParamsVal本身。”

我们不知道它可以发送什么,因此我们不能要求它发送ParamsVal对象。那可能不是它可以发送的对象。我们确实知道它可以发送的对象可以扩展它。但这不是有用的信息。

相反,您需要Sender<? super ParamsVal>。它的意思是“发件人。我不知道它发送的是什么。但是我确实知道,无论发送什么,它都是ParamsVal的超类型,或者可能是ParamsVal本身。”

由于发送方可以发送的任何东西都是ParamsVal的超类型,因此我们知道在任何情况下它都可以发送ParamsVal。

09-06 21:41