JVM方法的动态与静态绑定机制
在运行时的环境中,通过引用类型变量来访问所引用对象的方法和属性时,JVM采用以下绑定机制:
- 实例方法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由JVM动态决定的;
- 静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为实际上在编译阶段就已经做了绑定;
- 成员变量(包括静态变量和实例变量)与引用变量所声明的类型的成员变量绑定,这种绑定属于静态绑定,因为实际上在编译阶段就已经做了绑定。
例如,以下这段代码:
1 Base who = new Sub(); //who被声明为Base类型,引用Sub实例 2 System.out.println("who.var="+who.var); //打印Base类的var变量 3 System.out.println("who.staticVar="+who.staticVar); //打印Base类的staticVar变量 4 who.method(); //打印Sub实例的method()方法 5 who.staticMethod(); //打印Base类的staticMethod()方法
输出结果:
who.var=BaseVar who.staticVar=StaticBaseVar Sub method Static Base method
对于动态绑定,再看一下这段代码:
1 public class Base { 2 void method() { 3 System.out.println("Base"); 4 } 5 void test() { 6 method(); 7 } 8 } 9 10 public class Sub extends Base { 11 void method() { 12 System.out.println("Sub"); 13 } 14 public static void main(String[] args) { 15 new Base().test(); //调用类Base的method()方法 16 new Sub().test(); //调用类Sub的method()方法 17 } 18 }
从以上代码示例中可以看出:在运行环境中,当通过子类的实例去调用一系列的实例方法(包括一个方法调用的另一个方法)时,将优先和子类本身包含的实例方法动态绑定,如果子类没有定义这个实例方法,才会和从父类中继承来的实例方法动态绑定。