Найдите ошибку в этой цепочке Optional
Цепочка должна найти клиента и построить ответ. Она не компилируется. Выведите тип после каждого шага, скажите, ошибка на этапе компиляции или рантайма, и исправьте.
Ограничения:
getSessionInfoвозвращаетSessionInfo;findClientвозвращаетOptional<Client>createResponse(Client)принимаетClient, а неOptional
return Optional.of(request)
.map(sessionService::getSessionInfo) // Optional<SessionInfo>
.map(authService::findClient) // findClient возвращает Optional<Client>
.map(client -> createResponse(client)) // здесь ожидается Client
.orElse(noClientResponse());
Найдите и исправьте ошибку.
Это ошибка компиляции, а не рантайма. map(authService::findClient) оборачивает уже-Optional результат, давая Optional<Optional<Client>>. Поэтому в следующем map client — это Optional<Client>, а не Client, и передача его в createResponse(Client) не проходит проверку типов. Исправьте использованием flatMap для findClient: flatMap разворачивает один уровень, давая Optional<Client>, поэтому следующий map получает настоящий Client.
- ✗Называть ошибку рантаймовой, хотя она ловится при компиляции
- ✗Упускать, что
mapнад функцией, возвращающейOptional, вкладывает вOptional<Optional<T>> - ✗Хвататься за
.get()вместоflatMapдля разворачивания одного уровня
- →Когда использовать
map, а когдаflatMapнаOptional? - →Почему
Optional<Optional<T>>почти всегда признак проблемы в коде?
Разбор
return Optional.of(request)
.map(sessionService::getSessionInfo) // Optional<SessionInfo>
.flatMap(authService::findClient) // было map → Optional<Optional<Client>>; стало flatMap → Optional<Client>
.map(client -> createResponse(client)) // client теперь Client
.orElse(noClientResponse());
Тип после каждого шага:
Optional.of(request)→Optional<OnStartUpRequest>.map(getSessionInfo)→Optional<SessionInfo>.map(findClient)→Optional<Optional<Client>>— потому чтоfindClientсам возвращаетOptional, аmapоборачивает результат ещё раз- следующий
.map(client -> ...)получаетclientтипаOptional<Client>, аcreateResponseждётClient→ ошибка компиляции
Это именно ошибка компиляции: компилятор не может подобрать тип аргумента, до выполнения дело не доходит.
Исправление — заменить map на flatMap для findClient. flatMap разворачивает один уровень вложенности: вместо Optional<Optional<Client>> получаем Optional<Client>, и следующий map получает настоящий Client.