Java 8對泛型方法的調用含糊不清[重復]

[英]Java 8 call to generic method is ambiguous [duplicate]

This question already has an answer here:


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);

Compiler error:

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


How to rewrite these functions to work with type inference from introduced with Java8?


1 个解决方案



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中找到了新的通用目標類型推斷改進。它上面有一些堆棧溢出問題。比如這個。

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>).

Java 8可以根據它作為參數傳遞給的方法推斷泛型的返回類型。因此,當您調用CollectionUtils.append(ImmutableSet.of(1),obj)時,Java 8會嘗試從與您的某個追加方法匹配的調用靜態返回一個不可變集。在這個例子中,它可以考慮返回一個ImmutableSet 而不是你明顯試圖返回的ImmutableSet 。然后不清楚你是否正在調用append(Set ,Object)或append(Set ,Set )。

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.




  © 2014-2022 联系我们: