Java通用"捕获#n-of"编译错误

Wud*_*ong 2 java eclipse generics

我有以下定义:

public interface MessageResponseHandler<T extends MessageBody> {
    public void responsed(Message<T> msg);
}

public class DeviceClientHelper {
    public MessageResponseHandler<? extends MessageBody> messageHandler;

    setHandler(MessageResponseHandler<? extends MessageBody> h){
        this.messageHandler = h;
    }

    public someMethod(Object message){
        Message<? extends MessageBody> msg = (Message<? extends MessageBody>) message;
        if (this.messageHandler != null) {
            this.messageHandler.responsed(msg);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么在someMethod()方法中调用

this.messageHandler.responsed(msg);
Run Code Online (Sandbox Code Playgroud)

会在eclipse中给我一个有线编译器错误.就像是:

the method responsed(Message<capture#3-of ? extends MessageBody>) in
the type MessageResponseHandler<capture#3-of ? extends MessageBody> is
not applicable for the arguments (Message<capture#4-of ? extends
MessageBody>)
Run Code Online (Sandbox Code Playgroud)

什么是"catpure"在错误信息中意味着什么?

ata*_*lor 8

你说DeviceClientHelper有一个messageHandler子类MessageBody.并且someMethod还为某些子类提供了消息MessageBody.但是,没有什么要求它们是相同的子类MessageBody,因此调用responsed无效.

要使它们使用相同的子类,请DeviceClientHelper在特定的子类上创建泛型MessageBody:

interface MessageResponseHandler<T extends MessageBody> {
    public void responsed(Message<T> msg);
}

public class DeviceClientHelper<T extends MessageBody> {
    public MessageResponseHandler<T> messageHandler;

    void setHandler(MessageResponseHandler<T> h){
        this.messageHandler = h;
    }

    public void someMethod(Object message){
        Message<T> msg = (Message<T>) message;
        if (this.messageHandler != null) {
            this.messageHandler.responsed(msg);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,您的MessageResponseHandler界面可能不需要关心MessageBody该类.这取决于它实际使用的方式,但这样的事情可能会更好:

interface MessageResponseHandler {
    public void responsed(Message<? extends MessageBody> msg);
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以从messageHandler字段中删除泛型类型并保留原始someMethod实现.