我有一些具有这种通用结构的代码:
interface Func
这本身就足够了.现在我想变得更自由,如果有人,比如,一个Func< Number>或者Func< Object>而不是Func< Double>他们仍然可以将其传递给计算机.先验,这应该是足够安全的.很好,所以我把它改成了
public double compute(Func super Double> f) {
Func super Double> g = f;
if (someCondition())
g = oa -> Math.max(0,f.apply(oa));
...
不幸的是现在lambda没有进行类型检查(说Eclipse),因为oa的类型不能传递给f.apply.
将f本身赋值给g似乎并不担心编译器,如果要应用的参数是A而不是Optional< A>,则不会出现问题.
不幸的是,似乎没有办法命名? super double参数类型,所以我可以再次使用它作为g的类型和/或用老式的内部类替换lambda.
例如,这甚至在语法上都不允许:
public
是否有任何相当优雅的方式来完成这项工作?
到目前为止,我提出的最好的是
public double compute(Func super Double> f) {
if (someCondition())
return computeInner(oa -> Math.max(0,f.apply(oa)));
else
return computeInner(f);
}
private double computeInner(Func super Double> g) {
return g.apply(Optional.of(3.14)) + g.apply(Optional.empty());
}
编译器接受了这一点,但间接调用除了使类型检查器满意之外别无其他原因并不是我称之为优雅的.
最佳答案
尝试这个奇怪的技巧:
g = oa -> Math.max(0,f.apply(oa.map(a -> a)));
// ^----------^
像这样映射可选类型允许编译器将可选类型“转换”为一致类型.
这确实有创建新的Optional实例的缺点.
但是,当然,I asked this question会考虑这是否实际上是规范允许的内容,或者是错误.
就个人而言,我发现你的“目前为止最好”特别令人震惊.当然,这取决于真实代码的外观.