2010-02-10 92 views
18

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

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

感谢

+0

在什么情况下你真的需要明确对象转换接口类型? – harto 2010-02-10 02:20:22

+0

你在这里有一个非常有用的答案。我希望你选择它。 – orbfish 2011-11-22 18:37:32

回答

1

你可以施放某个对象的运行时类型是你想将它转换成什么亚型。

编辑:

是的,你想投就需要实现该接口,以便您成功投放它的对象。

+0

你在想这完全是错误的。你应该问的是“在什么情况下把'Foo'当作'IBar'来处理? – 2010-02-10 02:01:00

+0

如果我想要转换为该接口的对象扩展了实现接口的类,该怎么办?将避免运行时错误? – alan 2010-02-10 02:01:38

+0

噢好..我尝试重写我原来的评论,因为它没有真正有意义的第一次尝试 – alan 2010-02-10 02:02:10

27

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

  • 溯造型:如果你有一个参考 变量是指亚型 对象,你可以把它分配给一个 参考变量的亚型。 你必须做一个明确的演员才能做 这个,结果就是你可以用 这个新的参考变量访问子类型的成员 。

  • 上溯造型:您可以参考 变量赋值给一个超基准 变量显式或隐式。 这是一项固有安全的操作 ,因为该分配限制了新变量 的访问权限 。

,则需要实现接口直接或间接使接口类型分配类对象的引用。

+0

我不确定你是否写这个,复制它,或总结,但它很好,让我意识到我想要的是什么那样做没有意义。 – orbfish 2011-11-22 18:38:25

+0

例子会很有用 – 2013-03-15 21:21:49

+0

由于人工编写的文本而得到赞扬,而不是一些'B扩展A'的喋喋不休。 – 2015-03-26 19:12:52

1

如果:

interface MyInterface{} 

class MyClass implements MyInterface{} 

然后

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

是可能的。

2

有一种直观的方式来思考这个问题 - 你不是用一个转换来改变一个对象,而只是在已知类型的情况下做一些事情 - 换句话说,你只能转换成一种类型你的对象已经是。因此,只需查看“对象”链,查看适用于您的对象的类型。

因此,如果将链接定义在链中较高位置的某处(例如,如果您的类的父类实现了它等等),则您只能将其转换为接口仅限于。它必须是明确的 - 从你的问题,它听起来像你可能会认为,如果你实现方法“void foo()”,那么你应该能够转换到一个接口,定义方法“void foo()” - 这是有时被描述为"duck typing"(如果它像鸭子一样呱呱叫,它是鸭子),但不是java如何工作。

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); 

因为虽然Barrun()方法可以实施Runnable.run()Bar没有宣布实行Runnable所以不能投射到Runnable

Java要求您声明的实现接口名称。它没有duck typing,不像其他一些语言,如PythonGo

2

假设我们要投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.