Yar*_*lyk 5 java android dalvik
让我们假设我们有三个(或更多)类
公共课A {}
公共B级扩展A {}
公共类C扩展B实现G {}
假设每个类都有自己的20个(或更多)方法.
铸造到C与铸造到A对性能有更大的影响吗?Java编译如何在幕后工作?
在向下投射时,是否必须通过反射检查所有方法和字段是否存在?
编辑: 类的大小(字段和方法的数量)是否会在投射时影响性能?我对OpenJRE和Dalvik感兴趣.
作为参考,我知道可以毫无问题地完成向上转换.
转换的性能取决于 JVM 实现。
JLS 5.5仅确定了铸造的要求(包括递归算法),但没有对实施提出任何要求。实际上5.5.3中的运行时转换规则也是以同样的方式确定的。所有产生与建议算法相同结果的 JVM 实现都被视为正确的 JVM。
通常,向下转换C需要花费更多时间,因为 JVM 必须检查对象的运行时类型。当投射到A它时,没有理由进行相同的检查,因为Bextends A。
实际上,JVM并不关心方法和字段的数量。它仅比较类型层次结构,您可以使用反射检查相同的层次结构 ( o.getClass())
我制作了一个示例代码,如下所示,先是向下转型,然后是向上转型:
Object o = new Integer(1);
Integer i = (Integer) o;
Object o2 = i;
Run Code Online (Sandbox Code Playgroud)
编译后的字节码如下:
0 new java.lang.Integer [16]
3 dup
4 iconst_1 <-- 1 as a parameter to the constructor
5 invokespecial java.lang.Integer(int) [18] <-- constructor
8 astore_1 [o] <-- store in 'o'
9 aload_1 [o]
10 checkcast java.lang.Integer [16] <-- DOWNCAST CHECK, SPECIAL BYTECODE
13 astore_2 [i]
14 aload_2 [i]
15 astore_3 [o2] <-- WITH UPCAST NO CHECK
Run Code Online (Sandbox Code Playgroud)
因此,有一个特定的 JVM 指令用于检查给定类的堆栈顶部的元素。
对于 upcast,根本不需要检查。
类的大小(字段数、方法数、实际占用空间)并不重要,因为转换会检查Class(元数据,实际上是一个对象)。
层次结构级别的数量以及实现接口的数量(如果转换为接口)确实很重要,因为这是要检查的可遍历继承/实现树。
如果没有某种缓存用于此检查,我会感到惊讶。