向下转型给出 ClassCastException

问题描述 投票:0回答:3

两节课:

public class ClassA implements ClassC {
    private static final long serialVersionUID = 1111111111111111111L;
    public String varA;
}

public class ClassB extends ClassA implements ClassC {
    private static final long serialVersionUID = 4604935970051141456L;
    public String varB;
}

在我的代码中我有这样的声明:

ClassB classB;

和方法

我的方法()

返回一个

ClassA
对象。

如果我写:

classB = (ClassB) myMethod();

我以为我会有:

classB.varA = <a value from myMethod()>
classB.varB = null

但事实并非如此:我收到一个 ClassCastException

为什么?如何快速将

myMethod()
分配给
ClassB

java classcastexception extends
3个回答
1
投票

问题是你试图将

ClassA
向下转换为
ClassB
,这是不允许的,因为实际对象可能是
ClassX
ClassA
的另一个子类),它没有显式的转换。

请参阅以下示例,它将抛出

ClassCastException
(但编译得很好):

public class Main {
    public static void main(String[] args) {
        SubB var = (SubB) someMethod();         
    }

    private static Super someMethod(){
        return new SubA();
    }
}

class Super { }
class SubA extends Super { }
class SubB extends Super { }

代码编译完美:

  • someMethod()
    返回类型为
    Super
    的类。
  • SubA
    扩展了
    Super
    ,因此不违反方法定义
  • SubB
    扩展了
    Super
    ,因此它可以将
    Super
    类型的对象转换为
    SubB

然而,当您执行此操作时,您将尝试将

SubA
类型的对象强制转换为
SubB
,这是不可能的。

旁注:

  • 请勿使用
    ClassC
    来命名
    interface
  • 在类名中放入层次结构作为小示例(Super <-> Sub)而不是(A <-> B <-> C)

1
投票
Java 中的强制转换与 C++ 中指针的动态强制转换不同。对于后者,如果类型不兼容,结果是空指针。在 Java 中,转换不兼容的引用会导致

ClassCastException<...>。


通常的 Java 惯用法是使用

instanceof

预先测试引用,然后仅在结果为 true 时才执行强制转换。例如,


ClassA a = myMethod(); if (a instanceof ClassB) { ClassB b = (ClassB) a; ... }



0
投票
ClassC

(接口),并将该引用存储为

ClassC
,然后您可以使用
ClassA
ClassB
。 A 是 C,B 是 C,但 A 不是 B,即使 B 是 A。如果有帮助的话。
    

© www.soinside.com 2019 - 2024. All rights reserved.