用于投射的Java规则

何时可以将某个对象转换为另一个对象? 铸造对象是否必须是另一个对象的子类型? 我正试图找出规则……

编辑 :我意识到我根本没有解释我的问题:基本上我正在将一个对象转换为接口类型。 但是,在运行时,我得到一个java.lang.ClassCastException 。 我的对象需要发生什么才能将其转换为此接口? 是否必须实施它?

谢谢

在Java中,有两种类型的引用变量:

  • 向下转换 :如果您有一个引用子类型对象的引用变量,则可以将其指定给子类型的引用变量。 您必须进行显式转换才能执行此操作,结果是您可以使用此新引用变量访问子类型的成员。

  • 上传 :您可以显式或隐式地将引用变量分配给超类型引用变量。 这是一种固有的安全操作,因为赋值限制了新变量的访问能力。

是的 ,您需要直接或间接实现接口,以便将类对象引用分配给接口类型。

假设我们要将d对象强制转换为A,

A =(C)d;

因此编译器和JVM已经检查了内部3个规则。 编译器在编译时检查前2个规则,JVM将在运行时检查最后一个规则。

规则1(编译时间检查):

‘d’和C的类型必须有一些关系(从孩子到父母或父对子或同一时间)。如果没有关系,那么我们将得到编译错误(不可转换的类型)。

规则2(编译时间检查):

‘C’必须是’A’的相同类型或派生类型(子类),否则我们将得到编译错误(不兼容的类型)。

规则3(运行时exception):

运行时对象类型’d’必须相同或派生类型为’C’否则我们将获得运行时exception(ClassCastExceptionexception)。

找到以下示例以获得更多想法,

 String s = new String("hello"); StringBuffer sb = (StringBuffer)s; // Compile error : Invertible types because there is no relationship between. Object o = new String("hello"); StringBuffer sb = (String)o; // Compile error : Incompatible types because String is not child class of StringBuffer. Object o = new String("hello"); StringBuffer sb = (StringBuffer)o; // Runtime Exception : ClassCastException because 'o' is string type and trying to cast into StingBuffer and there is no relationship between String and StringBuffer. 

这将有效:

 class Foo implements Runnable { public void run() {} } Foo foo = new Foo(); System.out.println((Runnable) foo); 

但这不会:

 class Bar { public void run() {} } Bar bar = new Bar(); System.out.println((Runnable) bar); 

因为虽然Bar有一个可以实现Runnable.run()run()方法, 但是没有声明Bar实现Runnable所以它不能被强制转换为Runnable

Java要求您按名称声明实现的接口。 与其他语言(如Python和Go)不同,它没有鸭子类型

有一个直观的思考方式 – 你不是用一个演员来改变一个对象,你只是做了一个已经被允许的东西,如果已知类型 – 另外,你只能转换为你的对象的类型是。 因此,只需查看对象链“向上”以查看适用于您的对象的类型。

因此, 只有在链中更高的位置定义接口时才可以转换为接口(例如,如果您的类实现了它,等等)。 它必须是明确的 – 从你的问题来看,你可能会想到如果你实现方法“void foo()”那么你应该能够转换为定义方法“void foo()”的接口 – 这是有时被描述为“鸭子打字” (如果它像鸭子一样呱呱叫,它是一只鸭子)但不是java的工作方式。

如果对象的运行时类型是您尝试将其强制转换为的子类型,则可以强制转换。

编辑:

是的,您尝试投射的对象需要实现界面才能成功投射。

如果:

 interface MyInterface{} class MyClass implements MyInterface{} 

然后

 MyClass m = new MyClass(); MyInterface i = (MyInterface)m; 

是可能的。