Java如何通过隐式类型调用确定要调用的方法?
这个问题是在我和我的朋友们准备考试时出现的。调用静态赋值变量的方法时,我们注意到了奇怪的行为 代码>文字,我们开始: 现在,做什么Java如何通过隐式类型调用确定要调用的方法?,java,methods,type-conversion,Java,Methods,Type Conversion,这个问题是在我和我的朋友们准备考试时出现的。调用静态赋值变量的方法时,我们注意到了奇怪的行为 代码>文字,我们开始: 现在,做什么 D foo = new F(); foo.a(1); 这会带来什么?好。。它在F中运行方法a(双) 这就是我们认为发生的事情: 程序首先在静态类型D中查找a:无任何内容 转到它的超级类,C。不查找a(int),而是查找a(double) 决定这是我想要的签名(即a(double)),但首先,在所有这些搜索之后,让我们先看看它所说的动态类型 在F中运行a(双) 这是
D foo = new F();
foo.a(1);
这会带来什么?好。。它在F中运行方法a(双)
这就是我们认为发生的事情:
void a(int) {}
**在类C中,当运行上面的调用时,它会在F中给我a(int)
有人能解释一下这个过程中涉及的机制吗?为什么代码以这种方式运行/编译?这背后的技术原因是什么?关于类似的情况,还有什么需要注意的吗()原因是Java是静态类型的。参数类型的分派是在编译时完成的,而不是在运行时 编译代码时,编译器会看到您正在对静态类型为
D
的对象调用名为a
的方法。它在D
中查找兼容的方法,并找到一个方法(继承自C
)。它生成代码来执行对C.a(double)
的虚拟调用
在运行时,虚拟调用调度对象的实际类型(而不是参数!),因此它最终调用F.a(double)
,因为这会覆盖C.a(double)
对象的运行时类型是F
,而F
恰好有一个不同的方法,如果在编译时已知该方法,则该方法是有效的,这一事实与此无关。如果你想要这种行为,你需要反思
如果添加了
C.a(int)
,编译器将在D
中看到两个名为a
的不同方法,并根据重载规则,选择一个接受int的方法。要调用的方法在编译时解析,而不是在运行时解析。由于编译器只在编译时知道foo是一个D
,因此只有一个方法a(double)
,这就是调用的方法。但是,要调用的对象的a(double)
是动态的(在运行时),这就是为什么要调用F.a(double)
,而不是C.a(double)
这称为单分派:要调用的方法在其被调用的对象上是动态的,但在其参数类型上是静态的
如果你在
C
中完全删除了该方法,它就不会在F
中调用a(int)
,它只会编译失败,说它找不到该方法。哇,答案太好了!我现在将深入探讨这一点!
void a(int) {}