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;
所以:
所有这些类只有一个名为" f"提到的签名。
我现在宣布以下对象:
A a = new D();
B b = new B();
C c = new E();
1。为什么方法调用a.f(3)无法处理并返回错误?
如果我之前提到的是正确的,这就应该发生:
JVM查找具有签名f(int x)或任何兼容签名(使用强制转换)的方法的A类。它找到了应该兼容的方法f(短x),对吗?然后它在D类中查找这个非常精确的签名,并发现它执行D:f(短x)。根据我的书,这是不正确的,为什么?这可能是因为简短的实际上并不是对int的推广,因此JVM并不认为f(短x)适合于调用?因此,不会发现任何f方法兼容并将返回错误。
我检查了谷歌以及我能找到的任何其他资源(也在Stackoverflow上),但都非常明显且没有足够详细的答案,因此我认为这可能是一件好事,我希望它会把我们的答案将对未来的学生超载和覆盖战斗有用:)提前感谢。
答案 0 :(得分:1)
可以调用的唯一两种方法是:
A类:+f(short x): int; +f(String x): int;
为了使强制转换有效,我们需要隐式地将整数3强制转换为short或字符串。
但是你不能隐含地将整数3转换为较小的short。当然,它不能隐式地转换为字符串,因此无法处理。
编辑:
因为您将D类的实例放入A容器中,所以实例a只知道A方法。你必须将a的实例强制转换为D才能调用D的方法,这样就可以隐式地将int 3强制转换为double并调用f(double)
方法。
答案 1 :(得分:-2)
关于你的第二个问题(为什么方法调用错误)
您已经将自己置于一个需要担心的四个复杂事物的位置:重载,覆盖,数据类型转换和(可能)自动装箱。
最有趣的那个可能实际上是转换。 http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html
由于继承规则,对象a具有以下操作:
f(byte) (from D)
f(short) (from D)
f(double) (from C)
f(String) (from A)
但问题是,用值<3> em 调用此函数意味着&#34;整数常量为3。&#34;您不能隐式地将整数转换为字节或字符串,因为这是一个缩小的转换。但是,可以隐式地将整数转换为double或float。
所以我希望a.f(3)从C中评估f(double)。