何时可以将某个对象投射到另一个对象中?铸造对象是否必须是另一个对象的子类型?我正试图找出规则......
编辑:我意识到我根本没有解释我的问题:基本上我正在将一个对象转换为接口类型。但是,在运行时,我得到java.lang.ClassCastException
。我的对象需要发生什么才能将其转换为此接口?是否必须实施它?
由于
答案 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 typing和Python
等其他语言不同,它没有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;
是可能的。