tor*_*tal 4 java methods type-conversion
当我和我的朋友们为考试而学习时,这个问题就出现了.调用静态赋值变量的方法时,我们注意到了奇怪的行为.
代码>单词所以我们走了:
class C {
public void a(double x) {}
}
class D extends C {
void b() {}
}
class F extends D {
void a(int i) {}
void a(double d) {}
Run Code Online (Sandbox Code Playgroud)
现在,做
D foo = new F();
foo.a(1);
Run Code Online (Sandbox Code Playgroud)
这会给什么?嗯..它在F中运行方法a(双)!
这就是我们想到的事情:
它是否正确?这意味着它爬上层次结构以找到一些方法,如果从int到double的类型转换完成,它可以适合.在此之后它检查动态类型是否具有这个新解释的签名.
我注意到,如果我加入
void a(int) {}
Run Code Online (Sandbox Code Playgroud)
**在C类中,当运行上面的调用时,它会在F中给我一个(int)!
有人可以解释一下这个过程中涉及的机制吗?为什么代码以这种方式运行/编译?这背后的技术原因是什么?还有更多关于类似情况应该注意的事情()
原因是Java是静态类型的.参数类型的调度是在编译时完成的,而不是运行时.
编译代码时,编译器会发现您正在调用a在静态类型的对象上命名的方法D.它寻找兼容的方法D,并找到一个方法(继承自C).它生成代码以执行虚拟调用C.a(double).
在运行时,虚拟调用调度对象的实际类型(而不是参数!),因此它最终会调用F.a(double),因为这会覆盖C.a(double).
事件的运行时类型是F并且F恰好具有在编译时已知的有效的不同方法这一事实是无关紧要的.如果您想要这种行为,则需要反思.
如果添加C.a(int),编译器会看到两种不同的方法命名a中D,并根据超载规则,选择一个接受一个int.
| 归档时间: |
|
| 查看次数: |
218 次 |
| 最近记录: |