Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 泛型CompletableFuture和complete_Java_Generics - Fatal编程技术网

Java 泛型CompletableFuture和complete

Java 泛型CompletableFuture和complete,java,generics,Java,Generics,我构建了一个类来发送请求并从服务器接收响应 public class RequestManager { private final Map<String, CompletableFuture> requests = new ConcurrentHashMap<>(); public <T extends Response> void callback(String reqId, T resp) { this.requests.

我构建了一个类来发送请求并从服务器接收响应

public class RequestManager {
    private final Map<String, CompletableFuture> requests = new ConcurrentHashMap<>();

    public <T extends Response> void callback(String reqId, T resp) {
        this.requests.get(reqId).complete(resp);
    }

    public <T extends Response> CompletableFuture<T> sendAsync(Request req) {
        CompletableFuture<T> future = new CompletableFuture<>();
        String reqId = this.generateRequestId();
        this.requests.put(reqId, future);
        return future;
    }

    // omitted
}
这让我非常困惑,因为
T
也被定义为
T扩展响应
。我该怎么做才好呢

编辑:


但是,如果我将类型设置为<代码> MAP<代码> >代码> MAP或<代码> MAP

你应该考虑使整个类参数化。

public class RequestManager<T extends Response> {
    private Map<String, CompletableFuture<T>> requests = new ConcurrentHashMap<>();

    public void callback(String reqId, T resp) {
        this.requests.get(reqId).complete(resp);
    }
}
公共类请求管理器{
私有映射请求=新的ConcurrentHashMap();
公共无效回调(字符串请求ID,T响应){
this.requests.get(reqId).complete(resp);
}
}
在这种情况下,回调方法和请求映射的类型是一致的,并且是从封闭类派生的

或者,您可以将请求声明更改为:

Map<String, CompletableFuture<? super Response>> requests = new...

Map考虑
Response
的两个兄弟子类,例如
ByteResponse
IntResponse
。根据您编写的内容,将编译以下内容:

CompletableFuture<ByteResponse> byteRequest = new CompletableFuture<>();
requests.put("id", byteRequest);
callback("id", new IntResponse());
CompletableFuture byteRequest=newcompletablefuture();
请求。put(“id”,byteRequest);
回调(“id”,new IntResponse());
byteRequest
可以在代码中的其他地方访问,而调用
get()
的人可能会遇到一个可怕的惊喜


您不能将
T扩展响应
馈送到使用
的实例?扩展响应
,因为该实例可能需要与
T
完全不同的子类型。事实上,唯一可以传递的是null。根据您想做什么,您应该可以使用
Map
。使用
?超级响应
如果您真的希望您的请求映射尽可能通用。

感谢您的解释。但是,请将其更改为
?超级响应
在将物品放入地图时导致新错误。你能检查一下最新的问题,看看我该怎么办吗?谢谢。我的回答是,由于
callback()
方法的作用,您根本无法使用
CompletableFuture
。因此,
sendAsync
需要返回一个
CompletableFuture
或只返回
CompletableFuture
。这是您所能做的最好的。不幸的是,每个回调方法的类型都不一致。。。您的解决方案确实适用于
请求.get()
,但它会导致
请求.put()
出现新问题。你能检查一下最新的问题,看看我该怎么办吗?谢谢。put部分也可以用同样的方式修复,我已经更新了我的答案。当遇到泛型不一致的问题时,您也可以始终使用类强制转换,但这确实是一种最后的解决方案,应该不惜一切代价避免。对于非静态上下文,我通常会尽量避免使用泛型方法。参数化类几乎总是一种可行的方法。
Map<String, CompletableFuture<? super Response>> requests = new...
void create(String s, CompletableFuture<? super Response> resp) {
    getRequests().put(s, resp);
}
CompletableFuture<ByteResponse> byteRequest = new CompletableFuture<>();
requests.put("id", byteRequest);
callback("id", new IntResponse());