加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 为什么这个方法调用失败? (泛型和通配符)

发布时间:2020-12-15 03:06:56 所属栏目:Java 来源:网络整理
导读:我收到以下错误: 'call(ContainsMonitor)' cannot invoke 'call(? extends webscout.Monitor)' in 'WebScoutCallable' Monitor.java WebScoutCallable? extends Monitor handler;public setCallable(WebScoutCallable? extends Monitor callable) { this.ha
我收到以下错误:
'call(ContainsMonitor)' cannot invoke 'call(? extends webscout.Monitor)' in 'WebScoutCallable'

Monitor.java

WebScoutCallable<? extends Monitor> handler;

public setCallable(WebScoutCallable<? extends Monitor> callable) {
     this.handler = callable;
}

WebScoutCallable.java

public interface WebScoutCallable<T extends Monitor> {
     public void call(T caller);
}

ContainsMonitor.java

public class ContainsMonitor extends Monitor {
     public void handleDocument() {
          handler.call(this);
     }
}

我会自由地承认,我对于泛型并不熟悉Java本身.我发现错误消息令人困惑,因为它看起来应该工作(方法声明需要一个Monitor或子类,我传入一个子类).任何帮助(解释)将不胜感激!

谢谢!

解决方法

您的处理程序变量的type参数中有一个通配符.编译器不知道这个类型参数的确切类型是什么,只是它是Monitor或子类.

call方法采用T,在通配符上匹配.但是不能保证通配符类型是ContainsMonitor.它可以是一个监视器,也可以是MonitorSubtypeThatDoesntExistYet.因为编译器不知道实际类型,所以它不允许传递除null之外的任何内容,因为对于任何非null参数,它不能保证类型安全.

您可以通过删除通配符来解决此问题,并使用Monitor类上的类型参数替换该概念.

class Monitor<T extends Monitor<T>>
{
    WebScoutCallable<T> handler;

    public void setCallable(WebScoutCallable<T> callable) {
         this.handler = callable;
    }
}

接口WebScoutCallable在响应中稍有变化:

interface WebScoutCallable<T extends Monitor<T>> {
    public void call(T caller);
}

在扩展Monitor时,子类将自己的名称作为类型参数提供.

class ContainsMonitor extends Monitor<ContainsMonitor> {
     public void handleDocument() {
          handler.call(this);
     }
}

现在,T将是一个已知的类型,而ContainsMonitor将它定义为它自己,所以现在将它自己传递给调用是合法的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读