【发布时间】:2013-07-12 21:38:34
【问题描述】:
JVM如何选择执行哪个方法?
选择过程是否分为两部分。首先在编译 JVM 时寻找一个候选方法来执行。它将所需的签名选择到声明的对象类中(不是有效的)。一旦它选择了候选签名,它就会从对象的有效类开始在层次结构中查找它。
这正确吗?
还有一个问题:
这是一个类层次结构和相关方法:
- Class A: +f(short x): int; +f(String x): int;
- Class B extends A: +f(int x): int; +f(String x): int;
- Class C extends A: +f(double x): int; +f(byte x): int;
- Class D extends C: +f(byte x): int; +f(short x): int;
- Class E extends C: +f(char x): int; +f(int x): int;
所以:
- A 是 B 和 C 的超类
- B 是 A 的子类
- C 是 A 的子类
- C 是 D 和 E 的超类
- D 和 E 是 C 的子类
所有这些类都只有一个名为“f”的方法,带有提到的签名。
我现在声明以下对象:
A a = new D();
B b = new B();
C c = new E();
1.为什么方法调用 a.f(3) 无法处理并返回错误?
如果我之前提到的是正确的,这就是应该发生的:
JVM 在 A 类中查找带有签名 f(int x) 或任何兼容签名(带有强制转换)的方法。它找到了应该兼容的方法 f(short x),对吧?然后它在 D 类中寻找这个非常精确的签名,并发现它正在执行 D:f(short x)。根据我的书,这是不正确的,为什么?可能是因为 short 实际上并不是对 int 的提升,因此 JVM 不认为 f(short x) 适合调用?因此找不到任何兼容的 f 方法并会返回错误。
我检查了谷歌和我能找到的任何其他资源(也在 Stackoverflow 上),但都非常明显且没有足够详细的答案,因此我认为问这个问题可能是件好事,我希望它会变成我们的答案将对未来与重载和覆盖作斗争的学生有用:)提前致谢。
【问题讨论】:
-
整个过程在Java语言规范中有描述:docs.oracle.com/javase/specs/jls/se7/html/…
-
感谢您的建议。这绝对是我一直在寻找的文档。
标签: java overloading