Java 中集合的泛型和通配符
Generics and wildcards with collections in Java
在使用 AssertJ 的测试 class 中,我的代码类似于以下内容:
public void someTest() {
assertThat(getNames()).has(sameNamesAs(getExpectedNames()));
assertThat(getNames()).doesNotHave(sameNamesAs(getOtherNames()));
}
private List<String> getNames() {
return null;
}
private List<String> getExpectedNames() {
return null;
}
private List<String> getOtherNames() {
return null;
}
private Condition<List<String>> sameNamesAs(List<String> rhs) {
return new Condition<List<String>>("same names as " + rhs) {
@Override
public boolean matches(final List<String> lhs) {
return lhs.containsAll(rhs) && rhs.containsAll(lhs);
}
};
}
我在调用 has
和 doesNotHave
时遇到编译错误:
has/doesNotHave
(org.assertj.core.api.Condition<? super java.util.List<? extends java.lang.String>>)
in AbstractListAssert cannot be applied
to
(org.assertj.core.api.Condition<java.util.List<java.lang.String>>).
我是 Java 的新手,我不明白这个问题:java.util.List
是 java.util.List
的超类型,java.lang.String
扩展了 java.lang.String
,不是吗?
在您的情况下,has
和 doesNotHave
方法采用 Condition<? super List<? extends T>
条件,而不是 Condition<? super List<T>>
,因为您从 Condition<List<T>> sameNamesAs
方法返回.
您需要 Condition<List<? extends String>>
类型的实例(它是原始类型 Condition<? super List<? extends String>>
的子类):
private Condition<List<? extends String>> sameNamesAs(List<String> rhs) {
return new Condition<List<? extends String>>("same names as " + rhs) { ... };
}
我试图用以下片段来说明这一点:
List<String> list = getNames();
// ELEMENT = String, ACTUAL = List<? extends ELEMENT>
ListAssert<String> assertThat = assertThat(list);
// by the signature, we have to pass Condition<? super ELEMENT> or Condition<? super ACTUAL>
// Condition<? super ACTUAL> = Condition<? super List<? extends String>>
Condition<List<? extends String>> condition = sameNamesAs(list);
// Condition<List<? extends String>> extends Condition<? super List<? extends String>>
assertThat.has(condition);
在使用 AssertJ 的测试 class 中,我的代码类似于以下内容:
public void someTest() {
assertThat(getNames()).has(sameNamesAs(getExpectedNames()));
assertThat(getNames()).doesNotHave(sameNamesAs(getOtherNames()));
}
private List<String> getNames() {
return null;
}
private List<String> getExpectedNames() {
return null;
}
private List<String> getOtherNames() {
return null;
}
private Condition<List<String>> sameNamesAs(List<String> rhs) {
return new Condition<List<String>>("same names as " + rhs) {
@Override
public boolean matches(final List<String> lhs) {
return lhs.containsAll(rhs) && rhs.containsAll(lhs);
}
};
}
我在调用 has
和 doesNotHave
时遇到编译错误:
has/doesNotHave
(org.assertj.core.api.Condition<? super java.util.List<? extends java.lang.String>>)
in AbstractListAssert cannot be applied
to
(org.assertj.core.api.Condition<java.util.List<java.lang.String>>).
我是 Java 的新手,我不明白这个问题:java.util.List
是 java.util.List
的超类型,java.lang.String
扩展了 java.lang.String
,不是吗?
在您的情况下,has
和 doesNotHave
方法采用 Condition<? super List<? extends T>
条件,而不是 Condition<? super List<T>>
,因为您从 Condition<List<T>> sameNamesAs
方法返回.
您需要 Condition<List<? extends String>>
类型的实例(它是原始类型 Condition<? super List<? extends String>>
的子类):
private Condition<List<? extends String>> sameNamesAs(List<String> rhs) {
return new Condition<List<? extends String>>("same names as " + rhs) { ... };
}
我试图用以下片段来说明这一点:
List<String> list = getNames();
// ELEMENT = String, ACTUAL = List<? extends ELEMENT>
ListAssert<String> assertThat = assertThat(list);
// by the signature, we have to pass Condition<? super ELEMENT> or Condition<? super ACTUAL>
// Condition<? super ACTUAL> = Condition<? super List<? extends String>>
Condition<List<? extends String>> condition = sameNamesAs(list);
// Condition<List<? extends String>> extends Condition<? super List<? extends String>>
assertThat.has(condition);