pet*_*ter 40 java polymorphism casting
可能重复:
Java强制转换操作符如何工作?
Java强制实现
我总是想知道如何使用Java进行对象转换.我理解原始类型它会更像二进制表示级别,但是对象呢?有点像Polymorphism或者dynamic binding在某种程度上会在运行时确定一切吗?例如:
class Parent{
void A(){}
}
class Child extends Parent{
@Override
void A(){}
}
Parent p = new Parent();
Child c = (Child) p;
Run Code Online (Sandbox Code Playgroud)
这是如何在幕后工作的?它是否创建了一个新实例Child?而且,如果你试图施放会发生什么:
Child b = (Child) new Object();
Run Code Online (Sandbox Code Playgroud)
最后一个,在将一个原语转换为包装类时:
Double d = (Double) 3.3;
Run Code Online (Sandbox Code Playgroud)
我知道你没有必要施展它,但如果你这样做呢?在后端发生了什么重大事件?
ast*_*eri 17
当您使用显式转换时,系统中不会创建新对象(在您的最后一种情况下,您将基本类型转换为对象包装器,因为double它不是像Doubleis 的对象).请注意,由于Java的自动装箱功能,因此不需要此显式强制转换.
在您的(Child) new Object()场景中,您将收到ClassCastException,因为a Object不是a Child(尽管相反的情况属实).
第一个场景的答案是最复杂的.基本上,父类被视为接口可能是.当你施放的Child到Parent,只有ParentAPI是可用的.但是,仍将调用重写的方法.所以,如果你这样做:
Parent p = (Parent) new Child();
p.a();
Run Code Online (Sandbox Code Playgroud)
...的Child的public void a()将被调用,即使它正在通过的镜片观察Parent类.但是,如果你有在第二个方法Child是,Parent没有(假设public void b()为实例),你会不会能够调用,如果没有铸造对象回Child.
正如您所说,"在幕后",创建的唯一新事物是指向同一对象的另一个对象引用.您可以根据需要为同一个单一对象提供尽可能多的引用.考虑这个例子:
Parent p = new Parent();
Parent p1 = p;
Parent p2 = p;
Parent p3 = p2;
Run Code Online (Sandbox Code Playgroud)
在这里,有四个引用(p,p1,p2和p3),每个指向你所创建的同一对象new Parent()的声明.
不过,我可能会在哲学观点上争辩说,这种新引用的创建实际上是明确的,而不是在你说的时候Parent p = something.
链接:
Bev*_*ynQ 10
对你的主要问题的简单答案是否定的.所有演员都在语法检查时发生.
转换会影响语法检查器查看对象的方式,它不会影响对象本身,而Child转换为Parent,仍然是Child.
但是,仅在运行时检查演员表.这就是为什么它是危险的,除非没有别的办法,否则不应该使用它.
对此:checkcast,其作用是验证引用是否可分配。如果是,则不更改堆栈,并保留对该引用的操作。
因此,如果您有:
Child c = ( Child ) anyObject;
c.sayHi();
Run Code Online (Sandbox Code Playgroud)
如果强制转换成功,则sayHi 可以调用该方法:
如果可以将objectref强制转换为解析的类,数组或接口类型,则操作数堆栈不变;否则,checkcast指令将引发ClassCastException。
这是“字节码”
$ cat CastDemo.java
class Parent {}
class Child extends Parent {}
class Main {
Child c = (Child) new Parent();
}
$ javap -c Main
Compiled from "CastDemo.java"
class Main {
Child c;
Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: new #2 // class Parent
8: dup
9: invokespecial #3 // Method Parent."<init>":()V
12: checkcast #4 // class Child
15: putfield #5 // Field c:LChild;
18: return
}
Run Code Online (Sandbox Code Playgroud)
首先,要非常小心,不要将转换与转换混淆。它们可能共享表面语法,但过程却截然不同。
在Java中,您可以将对象向下转换为任何类型,但在运行时,ClassCastException如果该对象实际上与目标类型不兼容,您将得到一个。这发生在字节码级别:有一条专门用于向下转换的字节码指令。
Child c = (Child) new Object();
Run Code Online (Sandbox Code Playgroud)
将无条件地导致ClassCastException.
Double d = 3.3; // note: no explicit casting needed
Run Code Online (Sandbox Code Playgroud)
将在 的实例中执行自动装箱Double。所以这里,实际上创建了一个新的实例。
正常、成功的 dowcast 可能如下所示:
Object o = "a";
String s = (String)o;
Run Code Online (Sandbox Code Playgroud)
这里,没有创建任何对象:只有 的值o被复制到 中s。该值是一个参考值。