静态绑定和动态绑定用例

时间:2015-06-20 17:10:34

标签: java

我们知道私有,静态,最终和重载方法会发生静态绑定,而重写方法会发生动态绑定。 但是如果我的方法只是公开的,它既不是静态的,也不是覆盖和重载的。

public class Test{
    public void print(){
        System.out.println("hello!");
    }
    public static void main(String args[]){
        Test t = new Test();
        t.print();
    }
}

有人可以解释一下print()会发生什么绑定,因为它既不会被重载也不会被覆盖。

3 个答案:

答案 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的实际类型。