【发布时间】:2016-05-24 09:17:11
【问题描述】:
从具有 2 个字段的类 A 开始,name 和 id,一个构造函数和 getter,我编写了这个测试,它运行绿色:
@Test
public void test() {
List<A> list = Arrays.asList(new A(null, "a"), new A(null, "b"));
Collections.sort(list,
Comparator
.comparing(A::getName, Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(A::getId, Comparator.nullsLast(Comparator.reverseOrder())));
assertThat(list.get(0).id, is("b"));
}
但是,如果我在A::getName 上选择 Eclipse 的快速修复“提取到方法”:
下一行突然出现 2 个编译错误 (thenComparing(...)):
@Test
public void test() {
List<A> list = Arrays.asList(new A(null, "a"), new A(null, "b"));
Collections.sort(list,
Comparator
.comparing(extracted(), Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(A::getId, Comparator.nullsLast(Comparator.reverseOrder())));
assertThat(list.get(0).id, is("b"));
}
private Function<? super A, ? extends String> extracted() {
return A::getName;
}
说:
Test.A 类型未定义此处适用的 getId(capture#1-of ? super Test.A)
和
Comparator 类型中的方法 thenComparing(Function super capture#1-of ? super Test.A,? extends U>, Comparator super U>) 不适用于参数 (A::getId,比较器
>>)
为什么这会导致错误?我做错了什么?
【问题讨论】:
-
似乎是 Eclipse 类型推断的问题(与
javac一起使用)。尽管如此,通配符在返回类型中没有任何好处,所以无论如何你都应该声明private Function<A, String> extracted() { return A::getName; }。这应该可以解决您的问题。 -
既然我们确定报告编译错误是有充分理由的,那么是否有人提交了有关重构的错误,即。在前置条件检查期间请求此重构失败?