了解Java中的多个转换

Jes*_*mes 2 java inheritance casting

如果您想立即阅读问题,请跳至最后一句.

假设我们有一个接口和三个类:

interface I{}

class A implements I{}

class B extends A {}
Run Code Online (Sandbox Code Playgroud)

以下声明:

A a = new A();
B b = new B();
Run Code Online (Sandbox Code Playgroud)

现在,有一种经典的转换方式,它允许我将类型A(父类)的引用转换为类型B的对象(子类),如下所示:

 a = b; //here a is no longer pointing at object A, and is now pointing at the same object b is pointing at.
 b = (B) a; // the casting is now accepted by the compiler and during runtime as well.
Run Code Online (Sandbox Code Playgroud)

这里问题就在哪里.每当我看到一行代码都有多个转换时,我就无法读取它(字面意思),因此我无法理解它的含义.

例如,假设我们有这行代码:

a = (B)(I)b;
Run Code Online (Sandbox Code Playgroud)

你怎么读这个?a是对类型A的对象的引用,并且它被赋予类型B的对象的值(从左侧首先投射).但是等一下,b之前还有另一个演员(I).那么我们在这里有什么?它是一个被转换为(B)对象的接口吗?或者它是否被视为一个界面,也被投射为(B)?

我试图将其分解以避免混淆:

I temp = (I) b;// first line
a = (B) temp;// second line
Run Code Online (Sandbox Code Playgroud)

所以,首先,因为b是I(因为它扩展了实现I的A),所以编译器在运行时接受"第一行".

但是,"第二行",我们引用了一个对象A被赋予了类型B的值.乍一看,它没有任何问题.但后来我意识到I它不是A,也不是B,即使"第二行"中的演员阵容可以让编译器认为它是B类型的对象,但它不应该在运行时被接受.

所以我想回答的主要问题是如何解释以下行:

a = (B)(I)b;
Run Code Online (Sandbox Code Playgroud)

DwB*_*DwB 6

现实或你不想要的答案

这里真正的问题是粗心的goofball编写了糟糕的代码.真正的解决方案是; 要么不写蹩脚的代码或修复代码.

让我们继续作为一个傻瓜或你似乎想要的答案

java中有两种类型的转换; 向上和向下铸造.

向上转换是指将类型A的对象转换为接口I的实例; 你正在"继承"继承树.例如:

A aObject = new A();
I iObject = (I)aObject;  // Up casting.
Run Code Online (Sandbox Code Playgroud)

向上转换的好处是编译器能够在编译时确定转换是否合法.

向下转换是指将类型I的对象转换为类型A的对象; 你正在"继承"继承树.例如:

A aObject;
I iObject = new A();

aObject = (A)iObject;
Run Code Online (Sandbox Code Playgroud)

编译器在编译时不知道向下转换是否成功.因此,向下转换可能会在运行时抛出异常.

令人困惑的代码:a = (B)(I)b;是向上投射(安全)和向下投射(不安全)的一个例子.

作为奖励,铸造绝不是必需的.将B对象直接分配给A引用总是安全的,因为B类扩展了A类.

解决:"粗心的goofball"似乎是强大的语言.它不是强大的语言,它是描述你的情况的最好方法.事实上,编写这样的代码的人应该被终止(可选地,让你的竞争对手雇佣他们).