我想澄清一些关于绑定和派遣的事情。
绑定是将方法调用附加到方法签名。 Dispatch正在选择方法实现。首先来绑定,然后派遣。好的,我得到了这个,但是:
过去几天我读了很多解释,现在对我来说太乱了。其中一些是相互矛盾或完全相反的。据我所知,Java中的非static
,非private
和非final
方法默认为虚拟,必须使用动态绑定和动态调度。
答案 0 :(得分:2)
绑定是将方法调用附加到方法签名。 Dispatch正在选择方法实现。
绑定意味着你的意思是指超载。你所指的意义上的发货是指压倒一切。
首先是绑定,然后是派遣。
是。编译器执行绑定,JVM执行调度。
好的,我明白了,但是:
- 尚未覆盖的实例方法是否使用静态绑定?
醇>
没有。除了private
方法的情况外,编译器无法判断,在这种情况下,它使用invokespecial
字节码。
- 为什么重载方法确实使用静态绑定,因为它们是虚拟的并且可以在子类中重写?
醇>
他们没有。
据我所知,Java中的所有非静态,非私有和非最终方法都是虚拟的,必须使用动态绑定和动态分派。
正确。
答案 1 :(得分:0)
java中的绑定规则:
1)静态方法的调用是静态绑定的。
2)对构造函数的调用是静态绑定的。
3)调用非静态方法是动态绑定的:
<强>例外:强> 3.a)私有,非静态方法的调用是静态绑定的。
3.b)在子类中使用super
调用的非私有非静态方法也是静态绑定的。
那么对于第一个问题,即没有被覆盖的实例方法是否使用静态绑定?
答案为否。如果方法尚未被覆盖,但可以(将来)。因为它是一个实例方法,所以可以使用实例(动态绑定)调用或使用super(静态绑定)调用。
第二个问题:为什么重载方法确实使用静态绑定,因为它们是虚拟的并且可以在子类中重写?
答案:没有重载方法被静态绑定的事情。
<强>解释强>
class Sample{
public void method1(){
System.out.println("hello from A");
}
public void method1(String user){
System.out.println("hello "+user+" from overloaded method");
}
public static void main(String []argh){
Sample s = new Sample();
s.method1();
s.method1("name");
}
}
在上面的代码中,方法method1()
被重载,但由于它既不是静态的,也不是最终的,也不是私有的,因此它会生成invokevirtual指令,这意味着它是动态绑定的而不是静态的。
要清除绑定和调度的区别,请参阅此Question