java - 有哪些硬性 "rules"用于使用子类型进行转换?

标签 java casting subtyping

我正在为即将到来的 Java 期末考试尝试一些练习考试,我遇到了这个问题。

Consider the following class definitions and indicate whether 'Test.main()' would compile successfully. If it does compile, indicate whether it would run successfully or if not, indicate what Exception would be thrown.

public class A {
    public int method(int[] a) {...}
}
public class B extends A {
    @Override
    public int method(int[] a) {...}
}
public class C extends B {
    @Override
    public int method(int[] a) {...}
    public void otherMethod() {...}
}
public class Test {
    public static void main(String[] args) {
        A a = new C();
        B b = new B();
        b = (B) a;
    }
}

我认为 Test.main() 会编译但会抛出运行时异常,因为 a 是实际类型 C,而我们正试图将其转换为类型 B。事实并非如此,因为答案是这样说的很好。

我对涉及的层次结构比 2 层更深的转换规则感到很困惑。讲座幻灯片实际上没有此类信息!

那么,如果考试中出现此类问题,需要牢记哪些硬性“规则”?

最佳答案

当有复杂的层级时,试着把它画出来,这样更清晰:

A <- B <- C

I thought that Test.main() would compile but throw a runtime exception due to the fact that a is of actual type C and we are trying to cast it to type B.

a 的基础类型 C。但是,C 可以转换为 B A 因为 C 继承自 BB 继承自 A

基本上,引用类型转换是否成功的一般规则如下:

For any cast in the below format:

(X)Y

where X is a reference type and Y is a variable of a reference type, the cast will succeed at runtime if you can go from Y's underlying type to X in the inheritance hierarchy by only going along the directions of the arrows.

假设我们有这段代码:

A a = new A();
B b = (B)a;

这会失败,因为我们需要逆着箭头的方向从 AB


那么,您如何知道转换是否会在编译时失败?

这很容易。只需检查 Y变量类型(不是底层类型!)是否与 X 无关。

例如:

// these two types are unrelated
class Foo {}
class Bar {}

// ...
Foo f = new Foo();
Bar b = (Bar)f; // fails to compile

但是,如果 Y 的变量类型与 X 相关,则编译正常:

Object f = new Foo();
Bar b = (Bar)f; // Bar inherits from Object, so compiles fine.
                // But since Foo (f's underlying type) is unrelated to Bar
                // this crashes at runtime

关于java - 有哪些硬性 "rules"用于使用子类型进行转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44471908/

相关文章:

java - Libgdx 接触夹具

java - 在 Spring Boot 中实现模型继承有奇怪的数据存储库行为

c++ - 无法将 'v8::MaybeLocal<v8::String>' 转换为 'v8::Local<v8::Value>'

c++ - 如何在 vector C++ 中将 double 转换为 int?

java - 使用正则表达式从句子中查找带有 [a-zA-Z] 的单词

java - Java 中的向下转型会抛出 ClassCastException

javascript - 流的信息丢失是否与这种多态性固有的结构子类型有关?

scala - 从非协变类的实例创建协变类型类的实例

Scala UpperBound 和 LowerBound 概念

java - 我不知道如何为冒泡排序java定义变量