Gil*_*ili 5 java bounded-wildcard
鉴于:
public class Testcase {
public static <E> List<List<E>> transform(List<List<E>> list) {
return list;
}
public static <E> List<List<? extends E>> transform2(List<List<? extends E>> list) {
return list;
}
public static void main(String[] args) {
List<List<Integer>> known = new ArrayList<>();
List<List<? extends Number>> unknown = new ArrayList<>();
transform(known); // works
transform(unknown); // fails
transform2(known); // fails
transform2(unknown); // works
}
}
Run Code Online (Sandbox Code Playgroud)
编译器接受transform(known)但抱怨:
cannot infer type-variable(s) E
(argument mismatch; List<List<? extends Number>> cannot be converted to List<List<E>>)
where E is a type-variable:
E extends Object declared in method <E>transform(List<List<E>>)
Run Code Online (Sandbox Code Playgroud)
对transform(unknown).我遇到了相反的问题transform2().我已经咨询过PECS,我相信这transform()是正确的方法声明,但我不知道如何使用单一方法来处理这两种情况.
请注意,此问题仅发生在多级泛型中.List<? extends Number>工作得很好.问题并非特定于列表.你会得到它Future<Task<X>>等等.
什么方法声明将处理有界和无界泛型?如果不可能,为什么?
此方法适用的最具体类型似乎是? extends List<? extends ?>:
class Testcase {
public <E> List<List<E>> transform(List<List<E>> list) {
return list;
}
public <E> List<List<? extends E>> transform2(List<List<? extends E>> list) {
return list;
}
public <E> List<? extends List<? extends E>> transform3(List<? extends List<? extends E>> list) {
return list;
}
public void test(String[] args) {
List<List<Integer>> known = new ArrayList<>();
List<List<? extends Number>> unknown = new ArrayList<>();
transform(known); // works
// transform(unknown); // fails
// transform2(known); // fails
transform2(unknown); // works
transform3(known);
transform3(unknown);
}
}
Run Code Online (Sandbox Code Playgroud)
这是为什么这是有道理的解释。
AList<? extends Number>显然不是 a List<E>for any E,因为它不必能够插入最通用的实例E,因此第一个定义失败。
AList<Integer>符合List<? extends Number>,但这没有帮助,因为这些类型仍然不相等,因此类型List<List<Integer>>和List<List<? extends Number>>完全不相关。因此,第二个定义也失败了。
List<List<Integer>>相反,您想要的是和的使用站点最小上限List<List<? extends Number>>。List<A>您可以使用以下规则获取它:和的 use-site-LUB 为List<B>:
USLUB(List<A>, List<B>) = List<? extends USLUB(A, B)>
Run Code Online (Sandbox Code Playgroud)
现在,一步一步:
A = Integer和B = ? extends Number,最小上限是? extends Number,因为Integer符合? extends Number。List<Integer>和List<? extends Number>最小上限变为? extends List<? extends Number>List<? extends List<? extends Number>>。使用地点差异万岁;)
| 归档时间: |
|
| 查看次数: |
60 次 |
| 最近记录: |