`
seaizon
  • 浏览: 143868 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

动态绑定和静态绑定

    博客分类:
  • java
阅读更多
Java中绑定有两种形式静态绑定static-binding(早绑定early-binding)和动态绑定dynamic-binding(晚绑定late-binding,或运行时绑定runtime-binding)
静态绑定是在编译时绑定,而动态绑定是在运行时根据对象的实际情况来选择绑定父类或者是某个子类的方法。在执行效率上,静态绑定要优于动态绑定,但丧失了灵活性。
Java中变量是动态绑定的,实例方法是动态绑定的。在进行“向上转型”的时候子类会覆盖父类的实例方法而不会覆盖父类的变量。

1.Java的方法调用过程
编译器查看对象的声明类型和方法名(对象变量的声明类型)。通过声明类型找到方法列表。
编译器查看调用方法时提供的参数类型。
如果方法是private、static、final或者构造器,编译器就可以确定调用那个方法。这是静态绑定。
如果不是上述情况,就要使用运行时(动态)绑定。在程序运行时,采用动态绑定意味着:虚拟机将调用对象实际类型所限定的方法。
2.运行时(动态)绑定的过程
虚拟机提取对象的实际类型的方法表;
虚拟机搜索方法签名;
调用方法。
注意,这里说的是对象的实际类型。即在多态的情况下,虚拟机可以找到所运行对象的真正类型。
3.在向上转型情况下的动态绑定示例


Java代码
public class Father { 
    public void method() { 
       System.out.println("父类方法,对象类型:" + this.getClass()); 
    } 

  
public class Son extends Father { 
    public static void main(String[] args) { 
       Father sample = new Son();//向上转型 
       sample.method(); 
    } 

public class Father { public void method() { System.out.println("父类方法,对象类型:" + this.getClass()); } } public class Son extends Father { public static void main(String[] args) { Father sample = new Son();//向上转型 sample.method(); } }
结果1:
父类方法,对象类型:class samples.Son

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


Java代码
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(); 
    } 

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类中的成员变量时,并不是采用运行时绑定,而是一般意义上的静态绑定。所以在向上转型的情况下,对象的方法可以“找到”子类,而对象的属性还是父类的属性。
现在再进一步变化,在父类和子类中同时定义和赋值同名的成员变量name,并试图输出该变量的值。


Java代码
public class Father { 
    protected String name="父亲属性"; 
    
    public void method() { 
       System.out.println("父类方法,对象类型:" + this.getClass()); 
    } 

  
public class Son extends Father { 
    protected String name="儿子属性"; 
    
    public void method() { 
       System.out.println("子类方法,对象类型:" + this.getClass()); 
    } 
    
    public static void main(String[] args) { 
       Father sample = new Son();//向上转型 
       System.out.println("调用的成员:"+sample.name); 
    } 

public class Father { protected String name="父亲属性"; public void method() { System.out.println("父类方法,对象类型:" + this.getClass()); } } public class Son extends Father { protected String name="儿子属性"; public void method() { System.out.println("子类方法,对象类型:" + this.getClass()); } public static void main(String[] args) { Father sample = new Son();//向上转型 System.out.println("调用的成员:"+sample.name); } }
结果3:
调用的成员:父亲属性

这个结果表明,子类的对象(由父类的引用handle)调用到的是父类的成员变量。所以必须明确,运行时(动态)绑定针对的范畴只是对象的方法。
现在试图调用子类的成员变量name,该怎么做?最简单的办法是将该成员变量封装成方法getter形式。


Java代码
public class Father { 
    protected String name = "父亲属性"; 
  
    public String getName() { 
       return name; 
    } 
  
    public void method() { 
       System.out.println("父类方法,对象类型:" + this.getClass()); 
    } 

  
public class Son extends Father { 
    protected String name="儿子属性"; 
    
    public String getName() { 
       return name; 
    } 
    
    public void method() { 
       System.out.println("子类方法,对象类型:" + this.getClass()); 
    } 
    
    public static void main(String[] args) { 
       Father sample = new Son();//向上转型 
       System.out.println("调用的成员:"+sample.getName()); 
    } 

public class Father { protected String name = "父亲属性"; public String getName() { return name; } public void method() { System.out.println("父类方法,对象类型:" + this.getClass()); } } public class Son extends Father { protected String name="儿子属性"; public String getName() { return name; } public void method() { System.out.println("子类方法,对象类型:" + this.getClass()); } public static void main(String[] args) { Father sample = new Son();//向上转型 System.out.println("调用的成员:"+sample.getName()); } }
结果4:
调用的成员:儿子属性


java中的变量都是静态绑定的,方法的话只有static和final(所有private默认是final的)是静态绑定的.
要搞清楚动态绑定,首先搞清楚静态绑定是非常有帮助的。

      如果方法是private、static、final或者构造方法,编译器将可以准确地找到调用哪个方法。这种调用方式就是静态绑定。

      编译器在调用某一个具体方法时,可能存在该方法的多个重载形式,那么编译器接下来将进行重载解析(overloading resolution)。来找到对应的参数类型。但是如果每次调用方法的时候都进行搜索,时间开销太大,所以,虚拟机预先为每个类创建一个方法表,真正调用时候查找这张表就行了。
分享到:
评论
1 楼 loovle 2010-03-24  
好文。。。。。

相关推荐

    Java动态绑定和静态绑定.doc

    在Java编程语言中,动态绑定和静态绑定是两个重要的概念,它们涉及到方法调用和多态性。了解这两个概念对于深入理解面向对象编程至关重要。本文将详细探讨它们的区别,并通过实例来阐述它们的工作原理。 首先,让...

    深入理解C++的动态绑定和静态绑定

    在C++编程语言中,动态绑定和静态绑定是两种关键的多态实现方式,它们对于理解和编写高效、灵活的代码至关重要。多态性允许我们通过一个共同的基类接口访问不同派生类的对象,从而提高了代码的重用性和可扩展性。 ...

    java动态绑定和静态绑定用法实例详解

    "Java动态绑定和静态绑定用法实例详解" Java中的绑定机制是指将一个方法的调用与方法所在的类(方法主体)关联起来。Java中存在两种类型的绑定机制:静态绑定和动态绑定。 静态绑定是指在程序执行以前已经被绑定...

    深入理解C++的动态绑定与静态绑定的应用详解

    为了支持c++的多态性,才用了动态绑定和静态绑定。理解他们的区别有助于更好的理解多态性,以及在编程的过程中避免犯错误。需要理解四个名词:1、对象的静态类型:对象在声明时采用的类型。是在编译期确定的。2、...

    交换机实验帮助:交换机 VLAN,MAC与端口绑定,链路聚合,静态路由

    本实验主要涉及四个核心概念:VLAN(虚拟局域网)、MAC与端口绑定、链路聚合以及静态路由。以下是对这些知识点的详细解释: 1. **交换机恢复出厂设置**: - 当交换机的配置出现错误或需要更改网络环境时,恢复出厂...

    WPF绑定静态变量的示例代码

    在本文中,我们将深入探讨如何在Windows Presentation Foundation (WPF)中绑定控件到静态变量。WPF是一种用于构建桌面应用程序的强大框架,它允许开发者通过数据绑定机制将UI元素与后台数据模型紧密关联,实现视图与...

    WPF样式静态资源绑定

    静态资源绑定是WPF中一种强大的特性,允许开发者将样式、模板或其他可复用的UI元素作为资源存储,并在应用程序的不同部分进行引用,以实现统一的界面风格和高效的代码重用。 一、样式和模板 在WPF中,有两种主要...

    访问者模式商量篇:java的动态绑定与双分派_.docx

    在Java编程中,动态绑定和静态绑定是两种不同的方法调用机制,它们分别适用于不同的场景。动态绑定,也称为晚期绑定或多态性,是指在程序运行时根据对象的实际类型来决定调用哪个方法。静态绑定,又称为早期绑定,是...

    WPF绑定静态变量的示例代码(二)加上IValueConverter

    在本文中,我们将深入探讨如何在Windows Presentation Foundation (WPF) 中绑定静态变量,并通过使用IValueConverter接口来实现动态更新控件的显示。WPF是.NET Framework的一部分,它为构建丰富的桌面应用程序提供了...

    吕鑫:【C++语法与数据结构第22天】【第3堂课】动态绑定与静态绑定(面试题)

    1、讲解和演示动态绑定与静态绑定的概念与原理; 2、讲解和演示虚析构函数的概念与原理,并讲解为什么构造函数不能使用虚函数的原因;

    Java中的静态绑定和动态绑定Java开发Java经验技巧

    在Java编程语言中,静态绑定和动态绑定是两个至关重要的概念,它们关乎程序的执行效率和灵活性。了解这两个概念对于提升Java开发技能至关重要。 首先,我们来解释一下静态绑定(也称为早期绑定)。静态绑定主要涉及...

    Java 静态绑定与动态绑定深入分析

    Java中的静态绑定与动态绑定是面向对象编程中的关键概念,它们决定了方法调用的方式和时机。静态绑定(也称为早期绑定或编译时绑定)和动态绑定(也称为晚期绑定或运行时绑定)是Java中多态性实现的基石。 **静态...

    layui动态绑定事件的方法

    在前端开发中,动态绑定事件是一项非常重要的技术,尤其是在处理动态创建的DOM元素时。...通过上述方法,即使是动态添加到页面上的元素,也能确保事件能够正确地绑定和触发,从而为用户带来良好的交互体验。

    Java方法的动态绑定与静态绑定

    对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定。  静态绑定:  在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现。例如:C。  针对java简单的可以理解为程序编译期的...

    Delphi 动态绑定事件处理函数过程

    在 Delphi 编程环境中,动态绑定事件处理函数是一个强大的特性,它允许程序在运行时动态地连接事件和对应的处理函数,而不是在编译时静态地确定。这为开发提供了更大的灵活性,特别是在处理不确定数量的对象或者需要...

    Java多态中的动态绑定与静态绑定

    Java虚拟机的动态绑定与静态绑定 大家可能都知道Java面向对象的三大特性,封装,继承,多态,其中动态绑定就与多态有关,那什么是动态绑定呢? 1.动态绑定(auto binding):也叫后期绑定,在运行时,虚拟机根据具体...

    理解Java中的静态绑定和动态绑定

    在Java编程语言中,静态绑定和动态绑定是两种不同的方法调用机制,它们与面向对象编程密切相关。这两种绑定方式决定了程序在运行时如何选择和执行特定的方法。 静态绑定(早期绑定),也称为编译时绑定,是指在程序...

Global site tag (gtag.js) - Google Analytics