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

使用Eclipse编译器进行编译时,LocalVariableTypeTable中出现奇怪的“!*”条目

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

使用Eclipse编译器进行编译时,LocalVariableTypeTable中出现奇怪的“!*”条目

!
ecj使用该令牌在通用签名中对捕获类型进行编码。因此
!*
表示捕获了无限制的通配符。

在内部,ecj使用的两种风格

CaptureBinding
,一种实现JLS
18.4
称为“新鲜类型变量”,另一种实现捕获la
JLS
5.1.10(使用与“自由类型变量”相同的术语)。两者都使用产生签名
!
。仔细观察,在此示例中,我们有一个“旧式”捕获:
t
具有type
capture#1-of ?
,捕获
<T>
in
Stream<T>

问题是:JVMS
4.7.9.1。似乎没有为这种新鲜的类型变量定义编码(其他属性在源代码中没有对应关系,因此也没有名称)。

我无法为lambda

javac
发出任何信号
LocalVariableTypeTable
,因此它们可能只是避免回答这个问题。

鉴于两个编译器都同意推断

t
捕获,为什么一个编译器生成LVTT,而另一个则不生成?JVMS
4.7.14拥有这个

这种差异仅对类型使用类型变量或参数化类型的变量有意义。

根据JLS,捕获是新鲜的类型变量,因此LVTT条目很重要,并且在JVMS中没有为这种类型指定格式是遗漏的。

后果

上面仅描述和解释了现状,表明没有任何规范告诉编译器的行为与当前状态有所不同。显然,这不是完全理想的情况。

  1. 可能有人希望与Oracle联系,并提到Java 8引入了JVMS部分未涵盖的情况。一旦局部变量也受类型推断的影响,这种情况可能变得更加相关。
  2. 希望看到当前情况的负面影响的任何人都可以通过494198(ecj)报名参加,否则优先级较低。

更新:
同时,有人报告了一个示例,其中需要常规的
Signature
属性(不能机会性地省略)来编码无法根据JVMS进行编码的类型。在这种情况下,javac也会创建未指定的字节码。根据后续文章, 任何变量 都不应该
具有这样的类型,但我认为讨论尚未结束(顺便说一句,JLS尚未确保这一目标)。

更新2: 在收到规范作者的建议后,我看到了最终解决方案的三个部分:

(1)任何字节码属性中的每个类型签名都 必须 遵守JVMS 4.7.9.1中的语法。ecj

!
和javac 都不
<capturedwildcard>
合法。

(2)编译器 在不存在合法编码的 情况下 近似类型签名,例如,使用擦除而不是捕获。对于LVTT条目,这种近似应视为合法。

(3)JLS 必须 确保只有使用JVMS 4.7.9.1可编码的类型才会出现在必须生成Signature属性的位置。

对于ecj的将来版本,已解决(1)和(2)。我不能谈论javac和JLS何时进行相应修复的时间表。



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

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

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