我正在为即将到来的 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
继承自 B
和 B
继承自 A
。
基本上,引用类型转换是否成功的一般规则如下:
For any cast in the below format:
(X)Y
where
X
is a reference type andY
is a variable of a reference type, the cast will succeed at runtime if you can go fromY
's underlying type toX
in the inheritance hierarchy by only going along the directions of the arrows.
假设我们有这段代码:
A a = new A();
B b = (B)a;
这会失败,因为我们需要逆着箭头的方向从 A
到 B
那么,您如何知道转换是否会在编译时失败?
这很容易。只需检查 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/