3 回答
![?](http://img1.sycdn.imooc.com/545847aa0001063202200220-100-100.jpg)
TA贡献1828条经验 获得超13个赞
试试这个奇怪的把戏:
g = oa -> Math.max(0, f.apply(oa.map(a -> a))); // ^----------^
像这样映射可选类型的类型,可使编译器将“可选”的类型“转换”为一致的类型。
这确实存在创建新Optional
实例的缺点。
但是,当然,我问了一个问题,它在思考这是否实际上是规范所允许的东西或错误。
就个人而言,我认为您的“迄今为止最好的”并不特别糟糕。当然,这取决于实际代码的外观。
![?](http://img1.sycdn.imooc.com/545868b60001587202200220-100-100.jpg)
TA贡献1780条经验 获得超5个赞
总的来说,我发现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实例而导致运行时性能下降。
![?](http://img1.sycdn.imooc.com/54584cde0001d19202200220-100-100.jpg)
TA贡献1811条经验 获得超5个赞
解决方案是更改您的接口签名:
double apply(Optional<? extends A> a);
分析
考虑一下您的界面是否仅仅是:
double apply(A a);
这样就永远不会发生错误。
这是因为Double
可分配给Object
。编译器将自动调整类型。这意味着该接口实际上是:
double apply(? extends A a);
因此,您需要做的就是让您的界面具有这种适应能力。
func(Number)
可以接受Double
作为参数。
func(Optional<Number>)
也应该接受Optional<Double>
。
因此,您应该? extends
在您的界面上添加。
添加回答
举报