Java泛型模糊方法调用在以下示例中:
public class Foo {
public <Y, X extends Y> void set(Path<Y> attribute, X value) {
...
}
public <Y> void set(Path<Y> attribute, Expression<? extends Y> value) {
...
}
}
尝试调用第二种方法
Foo foo = new Foo();
Path<Object> path = new Path<Object>();
foo.set(path, new Expression<Object>(value));
Eclipse内部没有错误。但是在命令行上,编译错误:
error: reference to set is ambiguous
foo.set(path, new Expression<Object>(value));
^
both method <Y#1,X>set(Path<Y#1>,X) in Foo and method <Y#2>set(Path<Y#2>,Expression<? extends Y#2>) in Foo match
where Y#1,X,T,Y#2 are type-variables:
Y#1 extends Object declared in method <Y#1,X>set(Path<Y#1>,X)
X extends Y#1 declared in method <Y#1,X>set(Path<Y#1>,X)
T extends Object declared in class Foo
Y#2 extends Object declared in method <Y#2>set(Path<Y#2>,Expression<? extends Y#2>)
如何调用第二种方法?
答案 0 :(得分:0)
无法强制编译器选择任一版本的方法。正如评论中所述,考虑简单地以不同方式调用两种方法是明智的。
也许您应该考虑定义一个方法,而不是遵循更复杂的Expression
方法,并在必要时定义只返回给定常量值的表达式。
我认为您应该考虑使用lambda或Supplier<X>
来支持这些表达式:
public <X> void set(Path<X>, Supplier<? extends X> expression) {
// ...
X value = expression.get();
// ...
}
然后:
final Path1<Integer> daysInAWeek = ...;
final Path2<Date> today = ...;
foo.set(daysInAWeek, () -> 7); // the constant value returning expression.
foo.set(today, () -> Date.todaysDate()); // calculated when invoked.
每个foo.set
代码行都隐式声明了一个扩展Supplier
的内部类。您还可以创建实现Supplier
的命名顶级类,并将实例作为set
中的第二个参数传递。
此外,如果您坚持拥有自己的Expression
接口/类,只要它符合Supplier
等功能接口。