这两种铸造方式有什么不同吗?

时间:2015-05-13 11:45:07

标签: java casting bytecode

在以下代码中

Object o;

//getting o

Integer i = (Integer) o; //1
Integer j = Integer.class.cast(mapValue);  //2

//1//2之间有什么区别吗?

我的意思是,在JVM中,所有这些情况都将使用相同的字节码指令执行,是吗?

2 个答案:

答案 0 :(得分:4)

它也是一样的。但是如果你看一下实现:

public T cast(Object obj) {
    if (obj != null && !isInstance(obj))
        throw new ClassCastException(cannotCastMsg(obj));
    return (T) obj;
}

很明显,该方法已经完成了一些额外的检查。在类似于您的示例的类中使用javap -c可以看到字节码中转换为的内容:

这是简单的直接演员:

0:   aload_0
1:   getfield        #2; //Field o:Ljava/lang/Object;
4:   checkcast       #3; //class java/lang/Integer
7:   astore_1

这是使用Class.cast()方法:

11:  aload_0
12:  getfield        #2; //Field o:Ljava/lang/Object;
15:  invokevirtual   #4; //Method java/lang/Class.cast:(Ljava/lang/Object;)Ljava/lang/Object;
18:  checkcast       #3; //class java/lang/Integer
21:  astore_2

可以看出,有invokevirtual操作的开销,与这种方法可能不知道最终类的事实一致(如@screenmutt在他的回答中所写)。

干杯,

答案 1 :(得分:1)

正如安德斯所指出的,效果是一样的。

但是,如果您知道最终类,则只能使用第一个。在此示例中,您可以在不知道结束类的情况下进行强制转换。

Class toCast = getClassToCast();
toCast.cast(objectToCast);