用于强制转换的Java规则
什么时候可以将某个对象投射到另一个对象中?强制转换的对象必须是另一个对象的子类型吗?我正试图找出规则 编辑:我意识到我根本没有解释我的问题:基本上我是在将对象强制转换为接口类型。然而,在运行时,我得到一个用于强制转换的Java规则,java,casting,object,Java,Casting,Object,什么时候可以将某个对象投射到另一个对象中?强制转换的对象必须是另一个对象的子类型吗?我正试图找出规则 编辑:我意识到我根本没有解释我的问题:基本上我是在将对象强制转换为接口类型。然而,在运行时,我得到一个java.lang.ClassCastException。我的对象需要做什么才能将其强制转换到此接口?它必须实施吗 谢谢如果对象的运行时类型是您试图将其强制转换为的子类型,则可以强制转换 编辑: 是的,您尝试转换的对象需要实现接口才能成功转换。在Java中,有两种类型的引用变量转换: 向下广播
java.lang.ClassCastException
。我的对象需要做什么才能将其强制转换到此接口?它必须实施吗
谢谢如果对象的运行时类型是您试图将其强制转换为的子类型,则可以强制转换 编辑:
是的,您尝试转换的对象需要实现接口才能成功转换。在Java中,有两种类型的引用变量转换:
- 向下广播:如果您有参考资料 引用子类型的变量 对象,则可以将其指定给 子类型的引用变量。 您必须进行显式强制转换才能执行此操作 这,结果是你可以 使用访问子类型的成员 这个新的参考变量
- 向上投射:您可以指定一个引用 变量转换为超类型引用 显式或隐式变量。 这是一种本质上安全的操作 因为分配限制了 新系统的访问能力 变数
interface MyInterface{}
class MyClass implements MyInterface{}
然后
这是可能的 对此有一种直观的思考方式——你不是在用强制转换来更改对象,你只是在做一些已知类型时已经允许的事情——换句话说,你只能强制转换为你的对象已经是的类型。因此,只需“向上”查看对象链,看看哪些类型适用于您的对象 因此,只有在接口定义在链中较高的位置时(例如,如果您的父类实现了它,等等),才可以强制转换到接口。它必须是明确的-从你的问题听起来,你可能在想,如果你实现方法“void foo()”,那么你应该能够转换到一个定义方法“void foo()”的接口-这有时被描述为(如果它像鸭子一样呱呱叫,那就是鸭子),但不是java的工作方式 这将起作用:
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()
方法可以实现Runnable.run()
,但Bar
没有声明为实现Runnable
,所以不能强制转换为Runnable
Java要求您按名称声明实现的接口。与其他一些语言(如和)不同,如果我们想将d对象强制转换为 A=(C)d 因此,编译器和JVM在内部检查了3条规则。 编译器在编译时检查前两条规则,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.
你的想法完全错了。你应该问的是“在什么情况下,将此
Foo
视为IBar
有意义?如果我试图强制转换到该接口的对象扩展了实现该接口的类,该怎么办?这会避免运行时错误吗?哦,好吧。我尝试重新表述我的原始注释,因为它在开始时没有真正意义。在什么情况下,您实际上需要显式地将对象强制转换为其接口类型?这里有一个非常有用的答案。我希望你能选择它。我不确定你是写了这个,复制了它,还是总结了它,但它很好,让我意识到我试图做的事情毫无意义。因为人类编写的文本,而不是一些<代码>B扩展了代码>聊天,所以示例会有用。
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.