Java动态绑定机制
我们都知道多态这一概念,即对象的多种表现形式。
例如Class B 继承了Class A,子类和父类具有相同的方法,调用的时候不知道该用哪个的时候,此时为多态状态。
比如下面这个例子:
public class DynamicBindingTest {
public static void main(String[] args) {
// 多态: 一个对象的多种形态 a 和 b
B b = new B();
A a = new B();
System.out.println(a.doubleInt()); // 30
}
}
class A{
int i = 10;
int doubleInt(){
return i * 2;
}
}
class B extends A {
int i = 15;
int doubleInt(){
return i * 2;
}
}
可以看到,执行结果是40,因为B中重写了A中 doubleInt() 方法。
这是因为JVM利用了绑定机制。
绑定又分为静态绑定和动态绑定,顾名思义,二者的区别在于JVM调用的是static方法还是动态方法。
所谓动态绑定机制
- JVM在执行对象的非静态成员方法时,会将这个方法和对象的实际内存进行绑定,然后调用。
- 动态绑定机制和变量无关,只和方法有关。
带着以上两点,我们看另一个例子, 并思考此时程序会打印出什么结果?
public class DynamicBindingTest {
public static void main(String[] args) {
A a = new B();
System.out.println(b.doubleInt());
}
}
class A{
int i = 10;
int doubleInt(){
return i * 2;
}
}
class B extends A {
int i = 15;
}
打印结果: 20
因为此时JVM会先去 B 中寻找该方法,但B类中并没有声明该方法,B的实际内存中只有父类的 Class A 中声明了doubleInt()
方法,则会调用父类中的方法,只因为方法中 this.i
的 this
省略掉了,所以 i = 10,进而结果是 20 。
换句话说,动态绑定只在乎调用的方法和方法声明处的变量,而不考虑其他因素。
再留一道思考题:
public class DynamicBindingTest {
public static void main(String[] args) {
A a = new B();
System.out.println(b.doubleInt());
}
}
class A{
int i = 10;
int doubleInt(){
return getInt() * 2;
}
int getInt(){
return i;
}
}
class B extends A {
int i = 15;
int getInt(){
return i;
}
}
大家可以把结果和原因打在留言中。
内容参考尚硅谷的Kafka课程视频