Java字节码:局部变量的类型?
根据这篇文章
http://slurp.doc.ic.ac.uk/pubs/observing/linking.html#assignment:
我的问题:为什么字节码不包含局部变量的类型信息,而确实包含参数和返回值的类型信息? 解决方法
首先,有几种不同的类型概念.有编译时类型,包括泛型.但是,仿制代码在编译后不存在.
有一个变量的验证推断的静态类型,可以是int,float,long,double,returnaddress或对象引用.对象引用另外键入上限,所以所有引用都是java / lang / String的子类型.字段可以另外具有一个短类型:byte,short,char或boolean.这些被视为与执行目的相同,但具有不同的存储空间. 最后,存在与验证的静态类型相同的运行时类型,但是在对象引用的情况下,表示被引用的实例的实际类型.请注意,由于验证器懒惰,有些情况下运行时类型可能实际上不是验证类型的子类型.例如,声明的Comparable类型的变量实际上可以在Hotspot中保存任何对象,因为VM在验证时不检查接口. 编译时间信息不会被保留,除非通过反射和调试的可选属性.这是因为没有理由保留. 局部变量没有明确的类型信息(除了新的StackMapTable属性,但这是一个技术性).相反,当加载类时,字节码验证器通过运行静态数据流分析来推断每个值的类型.这样做的目的是不要像编译时类型检查那样捕获错误,因为假设字节码在编译时已经经过了这样的检查. 相反,验证的目的是确保指令对VM本身并不危险.例如,它需要确保您没有采取整数并将其作为对象引用进行间隔,因为这可能会导致任意内存访问和黑客入侵. 所以虽然字节码值没有显式的类型信息,但是它们有一个隐式类型,它是静态类型推断的结果.这些细节根据每个虚拟机的内部实现细节而有所不同,尽管它们应遵循JVM标准.但是你只需要担心手写字节码. 字段具有显式类型,因为VM需要知道其中存储哪种类型的数据.方法参数和返回类型以所谓的方法描述符进行编码,也用于类型检查.它们不可能自动推断,因为这些值可以来自或去任何地方,而类型检查是按照每个类进行的. 附:在谈论验证类型时,我省略了一些细节.对象类型还跟踪它们是否已被初始化,以及哪些指令在未初始化时创建它们.地址类型跟踪创建它们的jsr的目标. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |