用于强制转换的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.