我在Utils
类中具有以下可用方法:
protected <U> U withTx(Function<OrientGraph, U> fc) {
// do something with the function
}
protected void withTx(Consumer<OrientGraph> consumer) {
withTx(g -> {
consumer.accept(g);
return null;
});
}
使用myClass
的方法,我有:
withTx(g -> anotherMethod(g));
第二段代码有一个编译错误:
The method withTx(Function<OrientGraph, Object>) is ambiguous for the type myClass
我猜这来自编译器,编译器无法确定lambda是Consumer
还是Function
。有一种消除这种情况的高尚方法吗?
无论方法anotherMethod
返回(void
,Object
,什么),我都不想使用此返回值。
一种解决方法是:
withTx(g -> { anotherMethod(g); });
但是我想知道是否还有更好的方法,因为这会触发SonarLint
。
答案 0 :(得分:8)
摘自Joshua Bloch的“有效Java” :
不提供带有多个重载的方法,这些重载需要不同的 如果可以创建,则功能接口位于相同的参数位置 客户中可能存在的歧义。
避免此问题的最简单方法是不编写重载 在同一个参数中采用不同的功能接口 位置。
另一种可能的解决方案是为这两种方法使用不同的名称:
<U> U withTxFunction(Function<OrientGraph, U> fc);
void withTxConsumer(Consumer<OrientGraph> consumer);
一个很好的例子,可以在Java API
本身中找到,例如在IntStream
界面中:
mapToDouble(IntToDoubleFunction mapper);
mapToLong(IntToLongFunction mapper);
更新:
我想说明为什么编译器会抱怨?那是因为...
lambda g -> anotherMethod(g)
可以同时分配给Function<T, R>
和Consumer<T>
:
Function<T, R> func = g -> anotherMethod(g);
Consumer<T> consumer = g -> anotherMethod(g); // here you just ignore the return value
<T> T anotherMethod(T t) { ... }
因此,当您编写withTx(g -> anotherMethod(g))
时,会出现“歧义方法调用” 错误,编译器无法找出应该使用哪种重载方法:
withTx(function) OR withTx(consumer) ... ?
答案 1 :(得分:2)
实际上,您已经有了解决问题的方法,但是在另一个地方,因为您这样写:
withTx(g -> {
consumer.accept(g);
return null; // this calls the `Function` variant of `withTx`
});
但是无论如何,您都会遇到此问题,因为函数anotherMethod()
的返回类型为void
,并且编译器不知道从Function<OrientGraph, Void>
还是{{ 1}}。 Consumer<OrientGraph>
本身应该表示一个接受某些东西却什么也不返回的函数。
Consumer
明确调用withTx(g -> { anotherMethod(g); });
变体。
如果要调用Consumer
变体,请执行以下操作:
Function