用于投射的Java规则

时间:2010-02-10 01:53:31

标签: java casting object

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

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

由于

6 个答案:

答案 0 :(得分:30)

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

  • 向下转发:如果您有参考 引用子类型的变量 对象,您可以将其分配给 子类型的引用变量。 你必须做一个明确的演员 这个,结果就是你可以 使用访问子类型的成员 这个新的参考变量。

  • 上传:您可以指定参考 变量到超类型引用 变量显式或隐式。 这是一种固有的安全操作 因为作业限制了 新的访问功能 变量

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

答案 1 :(得分:4)

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

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.

答案 2 :(得分:3)

这将有效:

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有一个可以实施run()的{​​{1}}方法,但Runnable.run()未声明实现Bar所以它无法转换为Runnable

Java要求您通过 name 声明已实现的接口。与duck typingPython

等其他语言不同,它没有Go

答案 3 :(得分:2)

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

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

答案 4 :(得分:1)

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

编辑:

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

答案 5 :(得分:1)

如果:

interface MyInterface{}

class MyClass implements MyInterface{}

然后

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

是可能的。