栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

目标类型具有通配符时的泛型方法类型推断

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

目标类型具有通配符时的泛型方法类型推断

通配符的每种用法都有与之关联的不同类型。(通常,JLS将此称为“新鲜类型”。)例如,这就是这样的编译器错误的工作方式:

List<?> list0 = ... ;List<?> list1 = ... ;list0.add(list1.get(0)); // error

因为在这种情况下,编译器会给

list0
list1
提供单独的类型,因此在大多数情况下

reference_type_of(List<?>) != reference_type_of(List<?>)

如果您尝试类似的操作,则可以开始了解它如何适合于推论

{    List<?> list0 = ... ;    List<?> list1 = ... ;    test(list0, list1);}static <T> void test(List<T> list0, List<T> list1) {}

编译器发出错误的地方实际上告诉我们有关为

list0
和生成的类型的一些信息
list1

错误:类Ideone中的方法测试无法应用于给定类型;    测试(列表0,列表1);    ^  必需:List <T>,List <T>  **找到:List <CAP#1>,List <CAP#2>**  原因:不存在类型变量T的实例,因此          参数类型List <CAP#2>符合形式参数类型List <T>  其中T是类型变量:    T扩展在方法<T> test(List <T>,List <T>)中声明的对象  **其中CAP#1,CAP#2是新鲜的类型变量:    CAP#1扩展了对象的捕获范围    CAP#2扩展了对象的捕获范围**

(我的粗体为粗体。)这些

CAP#...
类型是在捕获转换期间生成的。它向我们展示的是,当检查方法调用的表达,
list0
list1
相互给予不同的类型。(对于需要对错误进行解释的用户:这是因为声明的
test
断言两个列表必须具有相同的代码
T
。)

因此,由于我们现在知道通配符与引用类型相关联,因此我们可以看到

List<?> empty = Collections.emptyList();

该调用将被推断为类似“上限为Object的新鲜类型”之类的东西。或象征性地,我们可以说编译器可能会看到类似

// target type       -->       inferred invocation type//     v     vList<CAP#1> empty = Collections.<CAP#1>emptyList();

虽然:当然,我们总是会猜测一点,因为这取决于编译器如何实现。从理论上讲,对于类似上面的琐碎分配的情况

emptyList()
,它不必做任何工作来生成正确的字节码。

另外,很抱歉,我今天不喜欢规格检查。从本质上讲,这里的类型推断通过生成一组约束来证明方法调用应该或不应该编译,从而起作用。18.5.2中描述的算法以这种方式合并了通配符。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/407165.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号