java – 什么方法声明接受有界和无界多级泛型?
作者:互联网
鉴于:
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
}
}
编译器接受transform(已知)但抱怨:
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>>)
变换(未知).我遇到了transform2()的相反问题.我已经咨询了PECS,我相信transform()是正确的方法声明,但我不知道如何获得一个方法来处理这两种情况.
请注意,此问题仅发生在多级泛型中.名单< ;? extends Number>工作得很好.问题并非特定于列表.您将获得Future< Task< X>>等等.
什么方法声明将处理有界和无界泛型?如果不可能,为什么?
解决方法:
这种工作最具体的类型似乎是?扩展列表<?延伸?>:
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);
}
}
这是为什么这是有道理的解释.
列表<? extends Number>显然不是List< E>对于任何E,因为它不必能够插入最通用的E的实例,因此第一个定义失败.
列表<整数>符合List<?扩展数字>,但这没有帮助,因为这些类型仍然不相等,因此类型List< List< Integer>>和列表< List<? extends Number>>是完全不相关的.因此,第二个定义也失败了.
你想要的是List< List< Integer>>的使用地点最小上限.和列表< List<?扩展数字>>.您可以使用以下规则获取它:List< A>的use-site-LUB和列表< B>是:
USLUB(List<A>, List<B>) = List<? extends USLUB(A, B)>
现在,一步一步:
>对于A =整数而B =? extends Number,最小上限是? extends Number,因为Integer符合?扩展数量.
>对于List< Integer>和列表<? extends Number>最小的上限变成了?扩展列表<? extends Number>
>因此最终结果是List<?扩展列表<?扩展数字>>.
Hurray用于使用场地差异;)
标签:java,bounded-wildcard 来源: https://codeday.me/bug/20190522/1153132.html