与基类和子类相关的Java Generic“不适用于参数”

时间:2016-03-31 21:55:52

标签: java generics wildcard extends

我确实找到了关于一般性问题的类似帖子,但是没有人以我能理解的方式捕获了我的问题。我希望有人可以帮我解决这个问题。

我尝试过很多东西,例如从不同的地方删除“?extends”并使用“?super”来查看是否有其他错误会指向我的解决方案。

以下代码:

final ResponseBase response = executor.execute(myRequest);

给我以下编译错误: “CommandExecutor类型中的方法execute(捕获#6-extends扩展RequestBase)不适用于参数(RequestBase)”

完整的代码清单:

public class MainClass {

    private final static Map<Class<? extends RequestBase>, CommandExecutor<? extends RequestBase, ? extends ResponseBase>> MAP = new HashMap<>();

    public static void main(String[] args) {

        final DummyCommandExecutor dummyCommandExecutor = new DummyCommandExecutor();
        MAP.put(MyRequest.class, dummyCommandExecutor);

        final RequestBase myRequest = new MyRequest();
        myRequest.setRequestString("this is my request");

        final CommandExecutor<? extends RequestBase, ? extends ResponseBase> executor = MAP.get(myRequest.getClass());

        final ResponseBase response = executor.execute(myRequest);

        System.out.println(response.getResponseString());
    }
}

interface CommandExecutor<T, R> {

    R execute(T object);

}

class DummyCommandExecutor implements CommandExecutor<MyRequest, MyResponse> {

    @Override
    public MyResponse execute(MyRequest request) {

        final MyResponse response = new MyResponse();
        response.setResponseString(request.getRequestString());

        return response;
    }

}

class MyResponse extends ResponseBase {

}

class ResponseBase {
    String responseString;

    public String getResponseString() {
        return this.responseString;
    }

    public void setResponseString(String responseString) {
        this.responseString = responseString;
    }
}

class MyRequest extends RequestBase {

}

class RequestBase {
    String requestString;

    public String getRequestString() {
        return this.requestString;
    }

    public void setRequestString(String requestString) {
        this.requestString = requestString;
    }

}

2 个答案:

答案 0 :(得分:0)

你不能在没有施法的情况下这样做。虽然您知道映射将为给定类型返回正确的命令执行程序,但编译器却没有,因此您需要告诉编译器不关心:

final CommandExecutor<RequestBase,ResponseBase> executor = (CommandExecutor) MAP.get(myRequest.getClass());

答案 1 :(得分:0)

你不能只匹配?与T

一个选项就是:

final CommandExecutor executor = MAP.get(myRequest.getClass());

如果地图返回smth不可投射

,当然你可以获得运行时异常