Java CompletableFuture能否在自身thenRun回调中调用get()方法?
编译失败原因
thenRun方法接收的参数是Runnable,这个函数式接口的方法没有入参,设计上就拿不到上游任务的返回值。- 你代码里lambda写的
this.get(),this指向的是lambda所在的外部类实例,根本不是f1这个CompletableFuture对象,和你要拿异步结果的需求完全不匹配。
推荐实现方案
直接换用thenAccept方法就行,这是CompletableFuture专门用来消费上游计算结果的链式方法,不需要在回调里手动调用get(),完全满足你要的紧凑链式写法,不需要在调用链外部处理返回值:
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(()->{ try { Thread.sleep(3000); } catch (InterruptedException e) { // 不要吞中断信号,恢复中断状态是标准写法 Thread.currentThread().interrupt(); } return 1; }); // 上游返回值会直接作为回调的入参传入 f1.thenAccept(result -> System.out.println(result));
非推荐的“硬实现”方式
如果你一定要坚持“在回调内部调用future自身get()拿结果”的逻辑,可以先声明future变量再完成赋值,绕开lambda的有效final引用限制,但这种写法完全多余:
CompletableFuture<Integer> f1; f1 = CompletableFuture.supplyAsync(()->{ try { Thread.sleep(3000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return 1; }); f1.thenRun(() -> { try { // 回调触发时future已经完成,get()会立刻返回结果,但属于冗余操作 System.out.println(f1.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } });
注意:这种写法没有任何实际价值:
thenRun本身就是在future完成后才会触发,此时再手动调用get()是多此一举,还要额外处理受检异常,性能和代码简洁度都不如直接用thenAccept。
内容的提问来源于stack exchange,提问作者Troskyvs
相关产品推荐
相关产品推荐

