繁体   English   中英

用于投射的Java规则

[英]Java rules for casting

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

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

谢谢

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

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

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

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

假设我们想将d对象转换为A,

A =(C)d;

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

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

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

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

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

规则3(运行时异常):

运行时对象类型'd'必须相同或派生类型为'C'否则我们将获得运行时异常(ClassCastException异常)。

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

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要求您按名称声明实现的接口。 与其他语言(如PythonGo)不同,它没有鸭子类型

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

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

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

编辑:

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

如果:

interface MyInterface{}

class MyClass implements MyInterface{}

然后

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

是可能的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM