Java 8对泛型方法的调用是模糊的 [英] Java 8 call to generic method is ambiguous
问题描述
我正在将Java7代码移植到Java8,我想出了以下问题。
在我的代码库中,我有两种方法:
I'm porting Java7 code to Java8, and I came up with a following problem. In my codebase I have two methods:
public static <T> ImmutableSet<T> append(Set<T> set, T elem) {
return ImmutableSet.<T>builder().addAll(set).add(elem).build();
}
public static <T> ImmutableSet<T> append(Set<T> set, Set<T> elemSet) {
ImmutableSet.Builder<T> newSet = ImmutableSet.builder();
return newSet.addAll(set).addAll(elemSet).build();
编译器在以下测试中返回有关方法追加的模糊匹配的错误:
Compiler returns error about ambiguous match for method append in following test:
@Test(expected = NullPointerException.class)
public void shouldAppendThrowNullPointerForNullSecondSet() {
ImmutableSet<Integer> obj = null;
CollectionUtils.append(ImmutableSet.of(1), obj);
}
编译器错误:
对append的引用是不明确的,CollectionUtils中的方法追加(java.util.Set,T)和CollectionUtils中的方法追加(java.util.Set,java.util.Set)匹配
reference to append is ambiguous both method append(java.util.Set,T) in CollectionUtils and method append(java.util.Set,java.util.Set) in CollectionUtils match
如何重写这些函数以使用Java8引入的类型推断?
How to rewrite these functions to work with type inference from introduced with Java8?
推荐答案
您已经在Java 8中找到了新的通用目标类型推断改进。它上面有一些堆栈溢出问题。 比如这一个。
You've found the new Generalized Target-type Inference improvements in Java 8. There's a few stack overflow questions on it. Such as this one.
Java 8可以推断出返回类型基于它作为参数传递的方法的泛型。所以当你调用 CollectionUtils.append(ImmutableSet.of(1),obj)
时,Java 8试图从静态中返回一个不可变集。
与您的追加
方法之一匹配的调用。在这个例子中,它可以考虑返回一个 ImmutableSet< Object>
而不是 ImmutableSet< Integer>
。显然是想回归。然后不清楚你是否正在调用追加(Set< Object>,Object)
,或追加(Set< Integer>,Set< Integer> )
。
Java 8 can infer the return type of a generic based on the method it's passed to as an argument. So when you call CollectionUtils.append(ImmutableSet.of(1), obj)
, Java 8 is attempting to return an immutable set from the static of
call that matches one of your append
methods. In this instance, it could think about returning a ImmutableSet<Object>
instead of the ImmutableSet<Integer>
that you're clearly trying to return. And then it's unclear if you're calling append(Set<Object>, Object)
, or append(Set<Integer>, Set<Integer>)
.
最简单的解决方案是重命名第二种方法 appendAll
。或者,您可以按照建议的修复此处将您的通话更改为:
The easiest solution is to rename the second method appendAll
. Or, you could follow the suggested fix here and change your call to something like :
CollectionUtils.append(ImmutableSet.<ImmutableSet<Integer>>of(1), obj);
我会坚持自己重命名第二种方法。当他们尝试使用该库时,它将为其他开发人员带来同样的悲痛。
I'd stick with renaming the second method myself though. It will save other developers the same grief when they try to use the library.
这篇关于Java 8对泛型方法的调用是模糊的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!