Java 正确覆盖CompletableFuture.cancel
我注意到,如果将来调用Java 正确覆盖CompletableFuture.cancel,java,completable-future,Java,Completable Future,我注意到,如果将来调用thenApply,则重写cancel方法不会生效。派生的未来不知道原始版本有这样一个覆盖的事实。下面的代码演示了这个问题 是否有任何方法可以正确地覆盖该方法而不丧失改变未来的可能性 import java.util.concurrent.CompletableFuture; 公共班机{ 公共静态void main(字符串[]args){ CompletableFuture未修改=新建CompletableFuture(){ @凌驾 公共布尔值取消(布尔值可能中断刷新){
thenApply
,则重写cancel
方法不会生效。派生的未来不知道原始版本有这样一个覆盖的事实。下面的代码演示了这个问题
是否有任何方法可以正确地覆盖该方法而不丧失改变未来的可能性
import java.util.concurrent.CompletableFuture;
公共班机{
公共静态void main(字符串[]args){
CompletableFuture未修改=新建CompletableFuture(){
@凌驾
公共布尔值取消(布尔值可能中断刷新){
System.out.println(“--->取消未修改”);
返回super.cancel(可能中断frunning);
}
};
未修改
.取消(真);
CompletableFuture modified=新的CompletableFuture(){
@凌驾
公共布尔值取消(布尔值可能中断刷新){
System.out.println(“--->取消修改”);
返回super.cancel(可能中断frunning);
}
};
未修改
。然后应用(x->x)
.取消(真);
System.out.println(“--->结束”);
}
//输出
//>任务:Main.Main()
//--->取消未修改的
//结束
}
没有直接的方法来做你想做的事情,因为然后apply
返回一个新的CompletableFuture
对象。
但是,如果确实需要这样做,可以尝试重写
CompletableFuture
类本身
让我解释一下!
CompletableFuture。然后apply()
方法进一步调用CompletableFuture
类的uniApplyStage
私有方法,在该类中创建要返回的新CompletableFuture()
实例。(我反编译了Java源代码以检查这一点。)
无法重写此方法,因为它是私有方法。但是,如果你,
CompletableFuture
uniApplyStage
方法更改为@Override
cancel方法根据我的诚实意见,把这个答案看作是最后的选择。 您需要Java 9或更高版本。然后,所有创建新的依赖未来的方法都将调用工厂方法
newIncompleteFuture()
,您可以覆盖该方法:
public static void main(String arg[]) {
class MyFuture<T> extends CompletableFuture<T> {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
System.out.println("customized cancel");
return super.cancel(mayInterruptIfRunning);
}
@Override
public <U> CompletableFuture<U> newIncompleteFuture() {
return new MyFuture<>();
}
}
MyFuture<Object> future = new MyFuture<>();
System.out.print("direct: ");
future.cancel(true);
System.out.print("indirect: ");
future.thenApply(x -> x).cancel(true);
System.out.print("even longer chain: ");
future.thenApply(x -> x).exceptionally(t -> null).cancel(true);
System.out.println("end");
}
但请记住,对于
CompletableFuture
,取消与带有CancellationException
的异常完成并无区别。因此,有人可以异常调用completeeexception(new CancellationException())
而不是cancel(…)
,达到相同的效果。因为然后apply
返回一个新的CompletionStage
,这似乎不太可能。