我正在将Java7代码移植到Java8,我想出了以下问题。 在我的代码库中,我有两种方法:
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();
编译器在以下测试中返回有关方法追加的模糊匹配的错误:
@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)匹配
如何重写这些函数以使用Java8引入的类型推断?
答案 0 :(得分:7)
您已经在Java 8中找到了新的广义目标类型推断改进。它上面有一些堆栈溢出问题。 Such as this one
Java 8可以根据传递给参数的方法推断泛型的返回类型。因此,当您调用CollectionUtils.append(ImmutableSet.of(1), obj)
时,Java 8会尝试从与您的of
方法之一匹配的静态append
调用返回不可变集。在这种情况下,它可以考虑返回ImmutableSet<Object>
而不是您明确要返回的ImmutableSet<Integer>
。然后不清楚您是在呼叫append(Set<Object>, Object)
还是append(Set<Integer>, Set<Integer>)
。
最简单的解决方案是重命名第二种方法appendAll
。或者,您可以按照建议的修正here进行操作,并将您的通话更改为:
CollectionUtils.append(ImmutableSet.<ImmutableSet<Integer>>of(1), obj);
我会坚持自己重命名第二种方法。当他们尝试使用该库时,它将为其他开发人员带来同样的悲痛。