作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
据我所知,如果一个方法是非静态和非私有(private)的,那么 invokevirtual 指令会被添加到字节码中,这会导致运行时动态绑定(bind),但在下面的程序中,为什么要进行编译时绑定(bind)。
class Fruit{
}
class Apple extends Fruit{
}
class MyTest{
public void show(Fruit f){
System.out.println("fruit");
}
public void show(Apple a){
System.out.println("apple");
}
public static void main(String[] args) {
MyTest t = new MyTest();
Fruit f = new Fruit();
t.show(f);
Apple a = new Apple();
t.show(a);
Fruit f1 = new Apple();
t.show(f1);
}
}
下面程序的输出是
Fruit
Apple
Fruit
我对下面这行代码有疑问
Fruit f1 = new Apple();
t.show(f1);
因为 show() 是一个导致 invokevirtual 的实例方法,在 invokevirtual 的情况下,后期绑定(bind)是根据对象的类型完成的,因此它应该打印“Apple”,那么为什么结果是“Fruit”这是基于引用的类型。
请纠正我错误的地方以及我缺乏动态和编译时绑定(bind)的知识或与此概念相关的任何误解。
最佳答案
它是一个虚方法调用,但是虚方法属于MyTest
,而不属于Fruit
。重写必须在方法的所有者中进行,而不是在作为显式参数传递给方法的类中进行。
覆盖使用被调用方法的所有者的运行时类型;而解析重载(基于方法的显式参数)发生在编译时,因此它取决于声明的参数的编译时类型。
如果您向 Fruit
添加了一个 show()
方法,您可以在 Apple
中覆盖它,它将是 Apple
一个被调用的。
例如
Fruit f = new Apple();
f.show(); // calls Apple.show, if it exists
关于java - 在方法重载中,方法解析发生在编译时还是运行时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64738025/
我是一名优秀的程序员,十分优秀!