程序绑定
程序绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。
对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定
静态绑定
静态绑定(前期绑定):在程序执行前方法已经被绑定。
在编译过程中就已经知道这个方法到底是哪个类中的方法,此时由
编译器或其它连接程序实现。例如:C。
针对java简单的可以理解为程序编译期的绑定;
java当中的方法只有final,static,private和构造方法是前期绑定
(如果一个方法不可被继承或者继承后不可被覆盖,那么这个方法就采用的静态绑定。)
动态绑定
动态绑定(后期绑定):在运行时根据具体对象的类型进行绑定。
若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,
编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。
动态绑定的过程:
-
虚拟机提取对象的实际类型的方法表
-
虚拟机搜索方法签名;
-
调用方法。
属性是静态绑定的
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Father { protected String name = "父亲属性"; } public class Son extends Father { protected String name = "儿子属性"; }
public static void main(String[] args) { Father sample = new Son(); System.out.println("调用的属性:" + sample.name); }
|
上述代码输出的是父亲属性
方法是动态绑定的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Father { protected String name = "FatherFatherFather";
public String getName() { return this.name; } }
public class Son extends Father { protected String name = "SonSonSon";
public String getName() { return this.name; } }
public class Main { public static void main(String[] args) { Father sample = new Son(); System.out.println(sample.getName()); } }
|
上述代码输出的是儿子属性
再来看一串代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class Test1 { public static void main(String[] args) { m(new GraduateStudent()); m(new Student()); m(new Person()); m(new Object()); } public static void m(Object o) { System.out.println(o.toString()); } } class GraduateStudent extends Student { } class Student extends Person { @Override public String toString() { return "Student"; } } class Person extends Object { @Override public String toString() { return "Person"; } }
|
上述代码输出结果如下:
1 2 3 4
| Student Student Person java.lang.Object@7852e922
|
总结
动态绑定体现了Java的继承与多态,在继承链中,JVM一直沿着继承链动态找到带有该方法的实现。