【问题标题】:Methods selection with Overloading and Overriding使用重载和覆盖的方法选择
【发布时间】: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 overloading


【解决方案1】:

唯一可以调用的两个方法是:

A类:+f(short x): int; +f(String x): int;

为了使转换有效,我们需要将整数 3 隐式转换为短字符串或字符串。

但您不能将整数 3 隐式转换为较小的 short。当然它不能隐式转换为字符串,因此无法处理。

编辑:

因为你把 D 类的一个实例放到了 A 容器中,所以实例 a 只知道 A 的方法。您必须将 a 的实例转换为 D 才能调用 D 的方法,然后才能将 int 3 隐式转换为 double 并调用 f(double) 方法。

【讨论】:

  • 嗯,感谢您对我的第二个问题的答复。关于可以调用的唯一两种方法是来自 A 的方法这一事实,我不完全确定我明白你的意思。
【解决方案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 调用这个函数 真的 意味着“3 的整数常量”。您不能将整数隐式转换为字节或字符串,因为这是一种缩小转换。但是,您可以将整数隐式转换为双精度或浮点数。

所以我希望 a.f(3) 从 C 中评估 f(double)。

【讨论】:

  • 这不是真的,a 不知道它是 D 的一个实例,因此如果不进行强制转换,您将无法访问不在 A 及其父级中的任何其他方法。
  • 嗨,马特,感谢您快速而清晰的回复。不幸的是,我可以向您保证,它不会评估 C: f(double) - 实际上,它根本不会评估返回错误 - 因为 a 对象来自 A 类,并且在编译期间 JVM 将寻找一个可辨认的A 中的签名,而不是 C 中的签名。因为在 A 中没有有效的签名,它只会返回一个错误。至少这是我怀疑的。我的主要疑问是:是否可以使用 A 中的 f(short x) 进行评估?有人回答说:不,你不能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-05
相关资源
最近更新 更多