Java动态绑定和静态绑定

  • 程序绑定
  • 静态绑定
  • 动态绑定


程序绑定

程序绑定:一个方法的调用与方法所在的类(方法主题)关联起来,即计算机要明确最终执行的方法是谁的方法。对Java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定

静态绑定

在程序执行前方法已经被绑定(在编译过程中就已经明确这个方法是哪个类的方法),此时,由编译器或其它连接程序实现。

注意:Java中只有 final,static,private修饰的方法和构造方法是前期绑定的。

关于final,static,private和构造方法是前期绑定的理解
1、对于private的方法,首先它不能被继承,既然不能被继承那么就没办法通过它子类的对象来调用,而只能通过这个类自身的对象来调用。因此就可以说private方法和定义这个方法的类绑定在了一起。
2、final方法虽然可以被继承,但不能被重写(覆盖),虽然子类对象可以调用,但是调用的都是父类中所定义的那个final方法,(由此我们可以知道将方法声明为final类型,一是为了防止方法被覆盖,二是为了有效地关闭java中的动态绑定)。
3、对于static方法:static方法可以被子类继承,但是不能被子类重写(覆盖),但是可以被子类隐藏。(这里意思是说如果父类里有一个static方法,它的子类里如果没有对应的方法,那么当子类对象调用这个方法时就会使用父类中的方法。而如果子类中定义了相同的方法,则会调用子类的中定义的方法。唯一的不同就是,当子类对象上转型为父类对象时,不论子类中有没有定义这个静态方法,该对象都会使用父类中的静态方法。因此这里说静态方法可以被隐藏而不能被覆盖。这与子类隐藏父类中的成员变量是一样的。隐藏和覆盖的区别在于,子类对象转换成父类对象后,能够访问父类被隐藏的变量和方法,而不能访问父类被覆盖的方法)
4、构造方法也是不能被继承的(子类是通过隐藏的super()来调用父类的无参构造方法,来完成对父类的初始化),因此编译时也可以知道这个构造方法到底是属于哪个类。

//父类
public class Father {
    public static void main(String[] args) {
        Father a = new Son();
        a.test();
    }
    public static void test(){
        System.out.println("父类");
    }
}
//子类
public class Son extends Father{
    public static void test(){
        System.out.println("孩子");
    }
}

动态绑定

后期绑定:在运行时根据具体对象的类型进行绑定

动态绑定的过程
1、虚拟机提取调用对象的实际类型的方法表。既可能是本类的方法,也可能是子类的方法表。
2、虚拟机搜索定义调用调用方法的签名的类。此时,虚拟机已经知道应该调用哪个方法。
3、最后,虚拟机调用方法。