我目前将我的CompletableFuture<X>
转换为CompletableFuture<Void>
,如下所示,但我想知道是否有更好的方法。
@Override
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenApply(c -> empty());
}
public Void empty() {
return null;
}
您正在有效地尝试将CompletableFuture
的已完成值转换为Void
类型的值。据推测,如果未来异常完成,您希望传播任何异常。
CompletableFuture
为这一基本转换提供了thenApply
,但也可以使用其他方法。
在您的情况下,您将要忽略源未来的值并返回null
,因为null
是Void
类型的唯一可能值。但是,需要为编译器提供一些提示,即您的目标是Void
类型。
通过为thenApply
的调用提供显式类型参数来显式化
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).<Void> thenApply(c -> null);
}
或者通过强制转换为lambda表达式中的相应类型
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenApply(c -> (Void) null);
}
您的解决方案实现了相同的结果,因为已知该值的类型正确,但它涉及额外的方法调用
@Override
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenApply(c -> empty());
}
所有这些解决方案都将传播原始qazxsw poi的异常(如果有的话)。
谢谢你CompletableFuture
,你也可以使用Luis与thenAccept
什么都不做:
Consumer
任何其他类型的行为都是相同的。 public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenAccept(c -> {}):
}
允许你对thenApply
的结果执行任何Function
。
例如,我可以有一个未来,这意味着完成CompletableFuture
,意味着转换为String
。
Integer
public static void main(String[] args) throws Exception {
CompletableFuture<String> futureLine = CompletableFuture.supplyAsync(() -> "1234");
CompletableFuture<Integer> theNumber = futureLine.thenApply(Integer::parseInt);
System.out.println(theNumber.get());
}
接收完成的值并通过将其传递给thenApply
的调用来进行转换。由于Integer#parseInt(String)
的返回类型为parseInt
,因此int
的返回类型被推断为thenApply
。