我们知道私有,静态,最终和重载方法会发生静态绑定,而重写方法会发生动态绑定。 但是如果我的方法只是公开的,它既不是静态的,也不是覆盖和重载的。
public class Test{
public void print(){
System.out.println("hello!");
}
public static void main(String args[]){
Test t = new Test();
t.print();
}
}
有人可以解释一下print()会发生什么绑定,因为它既不会被重载也不会被覆盖。
答案 0 :(得分:2)
无论方法是否已被覆盖,Java都将使用invokevirtual
来调用方法(并且那是动态的)。如果你看一下字节码
public static void main(java.lang.String[]);
Code:
0: new #5 // class Test
3: dup
4: invokespecial #6 // Method "<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #7 // Method print:()V
12: return
第9行显示了invokevirtual。现在,JIT编译器可能决定删除动态分派以实现更好的性能It is one of the used techniques。
答案 1 :(得分:1)
这里仍然会得到动态绑定,因为编译器不知道该方法没有覆盖。即时编译器可能会想出并优化调用,但就Java编译器而言,对方法print()
的绑定是动态的。
答案 2 :(得分:0)
你得到动态绑定。调用的实际test()
方法取决于对象的实际类型,而不是对象的声明类型。在您的示例中没有覆盖它并不重要,该方法仍然是虚拟的并且可以被覆盖。
请注意main()
具有静态绑定,因为(作为静态方法)main()
方法取决于类Test
的实际类型。