您实际上是在尝试将您的已完成值CompletableFuture
转换为 type 的值Void
。如果未来异常完成,大概你想传播任何异常。
CompletableFuture
提供thenApply
了这种基本转换,但也可以使用其他方法。
在您的情况下,您需要忽略来自源 future 和 return 的值null
,因为null
它是 type 唯一可能的值Void
。但是,编译器需要有一些提示,您的目标是 type 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());
}
所有这些解决方案都将传播原始CompletableFuture
.
感谢Luis,您也可以只使用thenAccept
无所事事Consumer
:
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
return realChannel.write(engineToSocketData).thenAccept(c -> {}):
}
任何其他类型的行为都是相同的。thenApply
允许您Function
对 a 的结果执行任何操作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
推断为CompletableFuture<Integer>
。