我有一些具有这种一般结构的代码:
interface Func<A> {
double apply(Optional<A> a);
}
class Foo {
public double compute(Func<Double> f) {
// Sometimes amend the function to do something slightly different
Func<Double> g = f;
if (someCondition())
g = oa -> Math.max(0, f.apply(oa));
return g.apply(Optional.of(3.14)) + g.apply(Optional.empty());
}
}
就其本身而言,这已经足够好了。现在,我想更加自由一些,这样,如果有人拥有aFunc<Number>或Func<Object>代替a的话,Func<Double>他们仍然可以将其传递给compute。先验的这应该是足够安全的。很好,所以我将其更改为
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似乎并不使编译器感到担心,并且如果to的参数apply为A而不是,也不会出现问题Optional<A>。
不幸的是,似乎没有成为一个方式来命名的? super Double参数类型,所以我可以再次使用它的类型g和/或用老式的内部类更换拉姆达。
例如,在语法上甚至不允许这样做:
public <T super Double> double compute(Func<T> f) {
Func<T> g = f;
...
有什么合理的优雅方法可以完成这项工作吗?
到目前为止,我想出的最好的方法是
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());
}
编译器接受了这一点,但是除了使类型检查器满意之外,间接调用实际上并不是我所说的“优雅”。
慕田峪7331174
翻阅古今
四季花海
相关分类