两种向下转型的区别

时间:2015-04-14 22:49:27

标签: java netbeans casting

public class {
    main() {
        // What is the different implications of these 2 down casts

        Superclass tRefVar = new SubClass();

        // Down cast example 1
        SubClass aVar = (SubClass) tRefVar;  

        // Down cast example 2
        ((SubClass) tRefVar).someMethodInSubClass();  
    }
}

含义,明智的,示例1强制转换和示例2强制转换之间有什么区别?

3 个答案:

答案 0 :(得分:1)

几乎没有区别。第一个示例创建一个新的局部变量,第二个示例不创建。就是这样。

稍微深入了解并确认一下,让我们考虑一下这个简单的类,有两种方法基本上与你在你的例子中所做的一样:

public class Downcasts {
  public int stringLength1(Object o) {
    String s = (String) o;
    return s.length();
  }

  public int stringLength2(Object o) {
    return ((String) o).length();
  }
}

这些方法的字节码(您可以使用javap -c Downcasts查看)是:

public int stringLength1(java.lang.Object);
  Code:
     0: aload_1
     1: checkcast     #2                  // class java/lang/String
     4: astore_2
     5: aload_2
     6: invokevirtual #3                  // Method java/lang/String.length:()I
     9: ireturn

public int stringLength2(java.lang.Object);
  Code:
     0: aload_1
     1: checkcast     #2                  // class java/lang/String
     4: invokevirtual #3                  // Method java/lang/String.length:()I
     7: ireturn

第一种方法可以做这些事情:

  • String s = (String) o
    • o加载到堆栈
    • 检查它是否为String
    • 将其存入寄存器2
  • return s.length()
    • 将寄存器2加载到堆栈(这是我们刚保存的那个)
    • 在其上调用String::length(虚拟函数)
    • 返回结果

第二种方法:

  • return ((String) o).length()
    • o加载到堆栈
    • 检查它是否为String
    • 在其上调用String::length(虚拟函数)
    • 返回结果

答案 1 :(得分:0)

铸造没有什么不同。示例#1使用临时局部变量而示例#2不使用。

这里的区别与例如完全相同。

int i = 0;

int j = i * 2;  // uses a temporary local
result = j + 1; //

result = (i * 2) + 1; // does not use a temporary local

答案 2 :(得分:0)

这些是相同的,你使用

SubClass aVar = (SubClass) tRefVar

如果您想多次重复使用aVar