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());