了解Java中的多类型转换 - java

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

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

interface I{}

class A implements I{}

class B extends A {}

以及以下声明:

A a = new A();
B b = new B();

现在,有一种经典的转换方式,它允许我将类型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.

问题就在这里。每次看到一行带有多个强制转换的代码时,我都不会(从字面上看)读取它,因此,我无法理解它的含义。

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

a = (B)(I)b;

您将如何阅读? a是对类型A的对象的引用,并且正在为其分配类型B的对象的值(首先从左侧开始强制转换)。但是请稍等,在b之前还有另一个强制转换(I)。那我们这里有什么?接口是否被转换为(B)对象?还是将b强制转换为接口,也将其强制转换为(B)?

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

I temp = (I) b;// first line
a = (B) temp;// second line

因此,首先,由于b是I(因为它扩展了实现I的A),因此“第一行”被编译器接受并在运行时接受。

不过,在“第二行”中,我们引用了为对象A分配了类型B的值。乍看之下,它没有任何问题。但是后来我意识到I既不是A也不是B,即使“第二行”中的强制转换可以欺骗编译器以为它是B类型的对象,但在运行时不应该接受它。

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

a = (B)(I)b;

参考方案

现实或您不想要的答案

真正的问题是,一个粗心的傻瓜编写了糟糕的代码。
真正的解决方案是;要么不要编写糟糕的代码,要么不要修改代码。

让我们保持愚蠢或似乎你想要的答案

Java中有两种类型的转换:向上和向下转换。

向上转换是将类型A的对象转换为接口I的实例时;您正在“继承”继承树。
例如:

A aObject = new A();
I iObject = (I)aObject;  // Up casting.

向上转换的好处是,编译器可以在编译时确定强制转换是否合法。

向下转换是将类型I的对象转换为类型A的对象。您正在“向下”继承树。
例如:

A aObject;
I iObject = new A();

aObject = (A)iObject;

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

您令人困惑的代码:a = (B)(I)b;是向上转换(安全)和向下转换(不安全)的示例。

另外,不需要任何铸造。
将B对象直接分配给A引用始终是安全的,因为B类扩展了A类。

解决:“粗心的愚蠢”似乎是强硬的语言。
它不是强硬的语言,而是描述您的情况的最好方法。
实际上,编写这样的代码的人应该被解雇(或者,被您的竞争对手之一雇用)。

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…

Java:从类中查找项目名称 - java

仅通过类的实例,如何使用Java反射或类似方法查找项目名称?如果不是,项目名称(我真正想要的是)可以找到程序包名称吗? 参考方案 项目只是IDE使用的简单组织工具,因此项目名称不是类或JVM中包含的信息。要获取软件包,请使用Class#getPackage()。然后,可以调用Package#getName()将包作为您在代码的包声明中看到的String来获取…

JAVA 8具有任何匹配属性的对象的过滤器列表 - java

我的要求是通过匹配任何属性的字符串来过滤对象列表。例如,假设Contact类具有三个属性:街道,城市,电话。我知道java流过滤器是如何工作的,在这里我必须将输入字符串与每个属性进行比较,如下所示:contactList.stream().filter(contact -> contact.getStreet().equals("dubai&…