Чем handle() отличается от whenComplete() у CompletableFuture

Оба метода вызываются независимо от того, как завершилась предыдущая стадия — успешно или с исключением. Разница в том, что происходит с результатом дальше.

whenComplete(BiConsumer) получает результат и исключение, но возвращает тот же CompletionStage с тем же результатом или тем же исключением. Это side effect: залогировать, закрыть ресурс — но не восстановить пайплайн.

handle(BiFunction) получает то же самое, но возвращает новое значение, которое становится результатом следующей стадии. Именно handle позволяет превратить упавший CompletableFuture в успешный — например, подставить дефолт при таймауте.

CompletableFuture result = future.handle((value, ex) -> { if (ex != null) { return "default"; } return value; });

Спросят следом: почему whenComplete не глушит исключение. Если оригинальный CompletableFuture упал, результат result всё равно останется падшим, даже если внутри whenComplete ничего не выбросили — его часто путают с try/catch, который перехватывает и гасит.

handle меняет исход. whenComplete меняет только побочный эффект.

Тренажёр: 600 вопросов, мок с таймером, план повторов

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки