2015-06-20 82 views
3

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

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

有人可以解释我print()的绑定发生了什么,因为它既没有超载也没有被覆盖。

+0

什么是“打印”?一个方法必须总是有一个返回类型。 – CKing

+0

请注意,重载的实例方法也是动态绑定的,就像任何其他实例方法一样。 –

+0

请注意,重载的实例方法也是动态绑定的...请问您可以用例子来解释吗? – user2068260

回答

1

您仍然在这里获得动态绑定,因为编译器不知道该方法没有覆盖。即时编译器可能会计算出来并优化调用,但就Java编译器而言,与方法print()的绑定是动态的。

+1

请注意,即使编译器知道它没有覆盖(因为该方法是最终的),如果最后的方法稍后变为非最终方法,仍然会有动态绑定。 –

0

您将获得动态绑定。实际调用的test()方法取决于不在对象的声明类型上的对象的实际类型。在你的例子中没有重写它并不重要,该方法仍然是虚拟的,可以被覆盖。

请注意,main()具有静态绑定,因为(作为静态方法)main()方法取决于类Test的实际类型。

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