Java 对象转换如何在幕后工作?

2022-09-01 00:39:04

可能重复:
Java强制转换运算符如何工作?
Java 转换实现

我一直想知道对象转换在Java中是如何工作的。我理解对于基元类型,它将更像二进制表示级别,但是Object呢?是有点像还是一切都将在运行时确定?例如:Polymorphismdynamic binding

class Parent{
     void A(){}
}
class Child extends Parent{
     @Override
     void A(){}
}

Parent p = new Parent();
Child c = (Child) p;

这在幕后是如何运作的?它是否创建 ? 的新实例?另外,如果您尝试投射,会发生什么情况:Child

Child b = (Child) new Object();

最后一个,当将基元转换为包装类时:

Double d = (Double) 3.3;

我知道你没有必要铸造它,但如果你这样做呢?后端是否发生了任何重大事件?


答案 1

使用显式强制转换时,不会在系统中创建新对象(除了在最后一种情况下,将基元类型强制转换为对象包装器,因为 不是像 is 这样的对象)。请注意,由于Java的自动装箱功能,这种显式强制转换不是必需的。doubleDouble

在您的方案中,您将收到一个 ClassCastException,因为 an 不是 a(尽管情况恰恰相反)。(Child) new Object()ObjectChild

第一个方案的答案是最复杂的。从本质上讲,父类被视为接口。将 转换为 时,只有 API 可用。但是,仍将调用重写的方法。因此,如果您这样做:ChildParentParent

Parent p = (Parent) new Child();
p.a();

...的将被调用,即使它是通过类的镜头看到的。但是,如果您在 中没有的第二个方法(例如,假设),则在不将对象转换回 .Childpublic void a()ParentChildParentpublic void b()Child

“幕后”,正如你所说,创建的唯一新事物是另一个指向同一对象的对象引用。您可以根据需要对同一个单数对象进行任意数量的引用。请考虑以下示例:

Parent p = new Parent();
Parent p1 = p;
Parent p2 = p;
Parent p3 = p2;

此处,有四个引用 (、 、 和 ),每个引用都指向使用声明创建的同一对象。pp1p2p3new Parent()

不过,我可能会在哲学观点上争论,这种新参考文献的创造实际上是明确的,而不是在幕后,当你说.Parent p = something

链接:


答案 2

你的主要问题的简单答案是否定的。所有强制转换都在语法检查时进行。

强制转换会影响语法检查器对对象的看法,它不会影响对象本身,子强制转换为父级,仍然是子级。

但是,仅在运行时检查强制转换。这就是为什么它是危险的,除非没有其他方法,否则不应该使用。


推荐