Проблема связана с тем, как Java делает вывод типа.
Ссылки на методы (и лямбда-выражения) являются поли-выражениями . Это означает, что одно и то же выражение может иметь различный тип, в зависимости от того, где оно используется.
Итак, ваше полиэкспрессия:
ofNullable(resp).map(obj1::get1)
имеет некоторый тип.
Если бы вы использовали его в контексте присваивания:
Optional<Object> opt1 = ofNullable(resp).map(obj1::get1);
Optional<?> opt2 = ofNullable(resp).map(obj1::get1);
, тогда оба этих параметра были бы хорошими, поскольку ограничения вывода типа позволяют параметру типа необязательного параметра соответствовать параметру типа переменная.
Однако, если вы используете выражение в качестве получателя вызова другого метода:
ofNullable(resp).map(obj1::get1).orElse(...)
, тогда Java сначала определяет тип ofNullable(...).map(...)
(больше не полиэкспрессия), а затем переходит к orElse
.
. Очевидно, что obj1.get1(resp)
возвращает не Object
, как вы утверждаете, а какой-то подстановочный тип. Это предполагаемый тип необязательного: Optional<some wildcard>
. Тогда параметр orElse
также должен иметь тип some wildcard
; единственное возможное значение для этого - null
.
. Существует несколько способов обойти это:
Вы можете явно присвоить результат ofNullable(...).map(...)
переменной типа Optional<Object>
, затем вызовите orElse
для переменной;
Вы можете привести к Optional<Object>
:
((Optional<Object>) ofNullable(...).map(...)).orElse(...)
Вы можете явно сопоставить объекту:
ofNullable(...).map(...).map(Object.class::cast)
Вместо этого можно использовать лямбду и привести результат к Object
:
ofNullable(...).map(r -> (Object) ...).orElse(...)
Или вы можете просто сделать это проще и не пытаться использовать Optional
:
Object s = (resp != null) ? obj1.get(resp) : ex.getMessage();