在Java中,绑定是针对类型而言的,通常指方法调用与方法定义的连接过程。绑定分两种:

  • 静态绑定,也称为前期绑定
  • 动态绑定,也称为晚期绑定

理解类型

1) 变量的类型

1
2
int value = 10;
// 变量value的类型是int类型

2) 引用的类型

1
2
3
4
5
6
class A {
public static void main(String[] args) {
A a;
}
}
// 引用a的类型是A

3) 对象的类型

1
2
3
4
5
6
7
class A {}
class B extends A {
public static void main(String[] args) {
B b = new B();
}
}
// b是类B的实例对象,也是类A的实例对象


静态绑定

静态绑定是发生在编译时期的,也称为前期绑定,因为绑定是发生在真正运行之前的。

上图中,a是Class A的引用变量,指向类A的实例对象;b是Class A的引用对象,指向类B的实例对象。

在编译期间,编译器在绑定时不检查特定引用变量所指向的对象的类型,它只检查调用方法的引用变量的类型,并检查在该类型中是否存在方法定义。

例如,对于上图中的a.func()方法调用,因为a是Class A类型,因此编译器会检查Class A中是否存在func()的方法定义。同样,对于b.func()方法调用,因为b是Class A类型,因此编译器会检查Class A中是否存在func()的方法定义。编译器并不会检查a、b到底是指向哪个对象。这种类型的绑定称为静态绑定。


动态绑定

动态绑定是发生在运行时,也称为晚期绑定,因为绑定是发生在程序真正运行时的。

在程序运行期间,会根据实际的对象进行绑定。例如,上图中的a.func()调用,将调用a指向的实际对象的func()方法。对于b.func()调用,将调用b指向的实际对象的func()方法。这种类型的绑定称为动态绑定。


静态绑定与动态绑定的区别

静态绑定 动态绑定
发生在编译期 发生在运行期
绑定与实际对象无关 绑定与实际对象有关
方法重载属于静态绑定 方法重写属于动态绑定
static、final、private、实例构造器、父类方法是静态绑定,因为它们不能被重写 左边表格的其它方法,是动态绑定,因为它们可以被重写