静态/动态绑定和静态/动态调度有点令人困惑

时间:2017-09-07 09:49:08

标签: java

我想澄清一些关于绑定和派遣的事情。

绑定是将方法调用附加到方法签名。 Dispatch正在选择方法实现。首先来绑定,然后派遣。好的,我得到了这个,但是:

  1. 尚未覆盖的实例方法是否使用静态绑定?
  2. 为什么重载方法确实使用静态绑定,因为它们是虚拟的并且可以在子类中重写?
  3. 过去几天我读了很多解释,现在对我来说太乱了。其中一些是相互矛盾或完全相反的。据我所知,Java中的非static,非private和非final方法默认为虚拟,必须使用动态绑定和动态调度。

2 个答案:

答案 0 :(得分:2)

  

绑定是将方法调用附加到方法签名。 Dispatch正在选择方法实现。

绑定意味着你的意思是指超载。你所指的意义上的发货是指压倒一切。

  

首先是绑定,然后是派遣。

是。编译器执行绑定,JVM执行调度。

  

好的,我明白了,但是:

     
      
  1. 尚未覆盖的实例方法是否使用静态绑定?
  2.   

没有。除了private方法的情况外,编译器无法判断,在这种情况下,它使用invokespecial字节码。

  
      
  1. 为什么重载方法确实使用静态绑定,因为它们是虚拟的并且可以在子类中重写?
  2.   

他们没有。

  

据我所知,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