繁体   English   中英

Java泛型方法调用

[英]Java ambiguous method call with generics

以下示例中的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>)

如何调用第二种方法?

无法强制编译器选择该方法的任何一个版本。 如评论中所述,明智的做法是简单地以不同的方式调用这两种方法。

也许您应该考虑定义一个更复杂的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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM