假设我们有三个(或更多)类

公共(public)类A {}

公共(public)类B扩展了A {}

公共(public)类C扩展B实现G {}

假设每个类都有自己的20个(或更多)方法。

是类型转换成C还是类型转换成A对性能有较大影响? Java转换在后台如何工作?

压下时是否需要通过反射检查所有方法和字段的存在性?

编辑:
类的大小(字段和方法的数量)是否会影响转换时的性能?
我对 OpenJRE Dalvik 都感兴趣。

作为引用,我知道可以毫无问题地进行向上转换。

最佳答案

转换的性能取决于JVM的实现。

JLS 5.5仅确定转换的要求(包括递归算法),但不对实现设置任何要求。实际上,runtime cast rules in 5.5.3也以相同的方式确定。产生与所提出算法相同结果的所有JVM实现均被接受为适当的JVM。

通常,由于JVM必须检查对象的运行时类型,因此将其转换为C会花费更多时间。强制转换为A时,没有理由进行相同的检查,因为B扩展了A

实际上,JVM并不关心方法和字段的数量。它仅比较类型层次结构,您可以通过反射来检查它(o.getClass())

我制作了一个示例代码,如下所示,一个向下转换,然后一个向上转换:

Object o = new Integer(1);
Integer i = (Integer) o;

Object o2 = i;

编译后的字节码如下:
 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

因此,有一条特定的JVM指令使用给定的类检查堆栈顶部的元素。

有了上流,根本没有检查。

类的大小(字段数,方法,实际占用空间)无关紧要,因为强制转换会检查Class(实际上是对象的元数据)。

层次结构级别的数目以及如果已实现的接口(interface)(如果强制转换为接口(interface))的数目确实很重要,因为这是要检查的可遍历的继承/实现树。

如果没有用于此检查的某种缓存,我会感到惊讶。

10-06 06:53
查看更多