Чем 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 — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки