频道栏目
首页 > 程序开发 > 综合编程 > 其他综合 > 正文
Java静态绑定&动态绑定解析
2018-09-28 14:34:16      个评论      
收藏   我要投稿

1:理解Java中方法调用的过程

1)编译器查看对象的生命类型和方法名,假设调用 x.f(param),且隐式参数 x 生命为 C类的对象,因为可能存在多个方法名为 f 的方法 eg:f(int) , f(double) 编译器会列举出 C 类中名为 f 的方法和其父类中访问属性为 public 且名为 f 的方法(因为父类的私有方法不可访问)

2)重载解析:编译器根据 方法的参数类型 选择合适的方法调用,因为存在类型转换(int可以转换成Double )这个具体的寻找方法的过程可能很复杂,如果编译器没有找到跟参数类型匹配的方法,或者有多个与参数类型匹配的方法 编译期间会报错。

3)上面阶段2 编译器已经获取了需要调用方法的 方法名字和参数,下面开始进行绑定:

1:如果方法是 private 方法,static方法,final方法,或者构造器 编译器就可以准确知道应该调用那个方法,我们将这种调用方式成为 静态绑定 (static binding) =》 因为 statci 和 final 方法不能被继承,private声明的方法和成员变量不能被子类继承,所有的private方法都被隐式的指定为final的(由此我们也可以知道:将方法声明为final类型的一是为了防止方法被覆盖,二是为了有效的关闭java中的动态绑定)

2:如果方法不是上面的这4种情况,编译器会进行动态绑定

4)当程序运行时,并且是采用动态绑定调用方法时,JVM 会调用与 X 所引用对象的实际类型最合适的那个类方法,假设X 类型是D类型,它是C的子类 如果 D 类中定义了 f(string) 方法,则会直接调用,不会去 C中查找 =》 为了避免每次调用方法都进行查找,虚拟机会预先为每个类 生成对应的方法表 ,方法表中记录了 所有方法的签名和实际调用的方法

2:动态绑定:

特性:无需对现存的代码进行修改,就可以对程序进行扩展。 eg:增加一个新类 Executive 并且变量 e能引用到这个类的对象 不需要对 e.getSalary() 代码进行重新编译,就能调用到 Executive.getSalary()方法

3:java 动态绑定在属性上 和 方法上的不同

1.Java的方法调用过程

编译器查看对象的声明类型和方法名(对象变量的声明类型)。通过声明类型找到方法列表。

编译器查看调用方法时提供的参数类型。

如果方法是private、static、final或者构造器,编译器就可以确定调用那个方法。这是静态绑定。

如果不是上述情况,就要使用运行时(动态)绑定。

在程序运行时,采用动态绑定意味着:虚拟机将调用对象实际类型所限定的方法。

2.运行时(动态)绑定的过程

虚拟机提取对象的实际类型的方法表;

虚拟机搜索方法签名;

调用方法。

注意,这里说的是对象的实际类型。即在多态的情况下,虚拟机可以找到所运行对象的真正类型。

3.在向上转型情况下的动态绑定示例

Java代码

public class Person{

public void method() {

System.out.println(“父类方法,对象类型:” + this.getClass());

}

}

public class Manextends Person{

public static void main(String[] args) {

Person sample = new Man(); //向上转型

sample.method();

}

}

结果1:

父类方法,对象类型:class sample.Person

这个结果没有疑问,声明的是父类的引用(句柄),但准确的调用了子类的对象,调用method,在子类中没有该方法,所以去父类中寻找到并调用之。

现在修改子类,重写(override)method方法。

public class Son extends Father {

public void method() {

System.out.println(“子类方法,对象类型:” + this.getClass());

}

public static void main(String[] args) {

Father sample = new Son();//向上转型

sample.method();

}

结果2:

子类方法,对象类型:class samples.Son

这个结果也是意料之中的。调用method时,在子类中寻找到了该方法,所以直接调用之。

4.静态绑定成员变量

在处理Java类中的成员变量时,并不是采用运行时绑定,而是一般意义上的静态绑定。所以在向上转型的情况下,对象的方法可以“找到”子类,而对象的属性还是父类的属性。

总结:属性不能被虚拟调用,因为他不能被重写,而方法可以,它被对象的真实类型调用。

点击复制链接 与好友分享!回本站首页
上一篇:LoadRunner场景-事务与集合点解析
下一篇:IDEA创建maven项目详细步骤解析
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站