В общем, я нахожу, что вывод типа для суперграфов в Java является кошмаром. Есть много ошибок компилятора, и обычно трудно объяснить, почему компилятор отклонит определенный синтаксис, а не другие.
Тем не менее, вы можете обойти это хакерским способом, добавив f
в тип Func<Double>
. Это не совсем безопасный бросок; если f
имеет какое-либо состояние, мы можем предположить, что нижняя граница на f
равна Double
, когда на самом деле это может быть Number
или Object
. С броском вы не несете штраф за выполнение решения, предоставленного @AndyTurner, но неконтролируемые роли также не являются вашим другом.
public double compute(Func<? super Double> f) {
// Sometimes amend the function to do something slightly different
Func<? super Double> g = f;
if (someCondition())
g = oa -> Math.max(0, (((Func<Double>) f)).apply(oa));
return g.apply(Optional.of(3.14)) + g.apply(Optional.empty());
}
В целом, я бы рассмотрел решение, которое вы представили в вопросе быть лучшим решением проблемы. Это немного более подробный, но компилятор должен иметь возможность оптимизировать код. Вы не теряете безопасность времени компиляции с помощью непроверенных бросков, и вы не вводите дефрагментацию времени выполнения из-за создания дополнительных экземпляров Optional
.