zoukankan      html  css  js  c++  java
  • 函数绑定

    一,函数绑定

      函数绑定分为动态绑定和静态绑定。(绑定指的是调用)

      当写完代码后,可使用javap  -c  java文件.class,来查看java编译器为我们生成的字节码。(反汇编过程)

      具体操作:1,先在程序编辑界面,右击鼠标,然后选择 show in Explorer 就会将该代码生成的文件所在目录呈现出来。

           2,点击地址栏中的工程名,找到 out文件,打开并找工程名。

           3,找到该类的字节码文件,将地址栏中的地址删除,输入cmd回车,就会出现命令编辑器。

            4,输入   Javap -c 文件名.class   回车就会出现字节码文件。

                  

     在这段字节码中,第6行invokespecia指令代表调用构造函数,第10行invokestatic指令就是在以静态绑定的方法调用函数,第14行 invokevirtual指令就是在以动态绑定的方法调用函数

      ♥ static方法都是静态绑定调用,实例方法都是动态绑定调用

      ♥ 静态绑定,又可叫早期绑定,指的是编译时期的绑定,如果被调用的目标方法在编译阶段就是确定好的,且运行期保持不变,这种情况下就将调用方法的符号引用转化为直接引用。(#7 = Class)

      ♥动态绑定,又可叫晚期绑定,指的是运行时期的绑定,如果被调用的方法在编译阶段无法确定下来,也就是说,只能在程序运行期将调用的方法符号引用转化为直接引用,由于这种转化过程具备动态性,因此也被称为动态链接。

     1 class A{
     2     protected int a;
     3     private String str;
     4     private Integer data;
     5 
     6     public A(int val){        //构造函数
     7         System.out.println("A()");
     8         this.a = val;
     9     }
    10 
    11     public static void show(){     //静态方法
    12         System.out.println("static A.show");
    13     }
    14 
    15     public void func(){        //实例方法 
    16         System.out.println("instance A.func");
    17     }
    18     //此方法是对上面方法的重载
    19     public void func(int data){    //因为方法名相同,返回类型相同,仅参数列表不同
    20         System.out.println("instance A.func data");
    21     }
    22 }
    23 
    24 class B extends A{
    25 
    26     public B(int val) {
    27         super(val);
    28     }
    29 
    30     public static void show(){
    31         System.out.println("static B.show");
    32     }
    33 
    34     // 就构成重写(覆盖)的关系
    35     public void func(){     //返回值类型,方法名,参数列表相同,仅作用域不同
    36         System.out.println("instance B.func");
    37     }
    38 }
    39 
    40 
    41 
    42 public class 函数绑定 {
    43     public static void main(String[] args) {
    44         //B b = new B(20); // invokespecial 构造函数
    45         //B.show(); // invokestatic 静态方法
    46         //b.func(); // invokevirtual 实例方法
    47         A a = new B(20);
    48         A.show(); // 静态绑定A.show
    49         a.func(); //  动态绑定A.func   instance B.func
    50     }

     运行结果:

     

    代码分析:

         第一行是因为在新new一个对象时,JVM会自动调用该对象的构造函数。

         第二行 A.show( )为静态绑定,在编译阶段,就确定好了调用那个方法,所以此处运行后,哪个类调用方法,就直接调用哪个类的静态方法show( )。

         第三行 a.func( )为动态绑定,在运行时才能确定调用哪个方法。A a = new B(20);此句是说新定义了一个A型变量a,然后又新new了一个B型对象,并将该对象的引用赋给变量a,而此处a.func( )运行后,机器识别出func()方法为动态方法,需要动态绑定,然后通过 a 找到在堆上的对象B,然后通过对象B的地址末尾的方法表地址又找到B类型的方法表,在里面查找,发现 在B类中继承的A类 中的func() 方法的地址已被重写。所以此时访问到的func( )方法就是被B类重写后的方法。所以打印出来就是B类中的。

     

    注意

    1.

    ———————图一———————————————————————————————

      

     ———————图二———————————————————————————————

    —————————————————————————————————————— 

       图一说明:基类引用可以引用派生类对象

       图二说明:派生类引用不能引用基类对象

    (形象理解:将人类比作基类,将教授比作派生类,A a = new B(20);说明此处需要一个人,所以将教授派去完全可以。 B b = new A(20);而这句报错是因为,此处需要一个教授,而你给的是一个人,这个人可能只是一个学生,并不能满足需求。)

    2.把基类和派生类的继承结构,也经常称作从上到下的继承结构继承结构中的类型,只支持从下到上的转换,

       不支持从上到下的转换。(也就是说派生类[教授]可以转换为基类[人],但基类[人]不一定能转换成派生类[教授]。)

     扩充:

            1, final的应用场景有三个:

                   1.final int data = 10; 可以用来定义常量

                   2.final可以修饰类称作密封类,不能再被继承

           3.final可以修饰类的实例方法,称作密封方法,表示该方法不能再派生类中重写(覆盖)

       使用final关键字做标识有“最终的”含义  :

        ( final可以修饰类、方法、属性、变量 )

        final修饰类,则该类不允许被继承

        final修饰方法,则该方法不允许被覆盖(重写)

        final修饰属性,则该类的属性不会进行隐式的初始化(类的初始化属性必须有值),或者在构造方法中赋值(但只能选其一)

        final修饰变量,则该变量的值只能赋一次值,即常量

            2,继承结构中,基类和派生类的方法通常有两种关系:重载和重写

                重载:在一个类作用域中,函数名相同,参数列表不同

                重写:作用域不同,在基类和派生类中,返回值相同,函数名相同,参数列表也相同

                      ( 重写指的是派生类方法表中,派生类提供的重写方法,把基类相应的方法的地址给重写了(覆盖了))

            3,当父类中的成员变量的访问权限为private时,说明子类不能访问该变量,但此时该变量仍会被子类继承

           下来,只是不能访问它。对于被继承下来的方法和变量,可直接用     对象 . 方法  或 对象 . 变量  来掉用。

  • 相关阅读:
    MTK 定时器 休眠时的动作
    Troubleshooting MySQL Memory Usage
    disruptor
    Google Protocol Buffer 的使用和原理
    百度贴吧10亿量级LAMP架构分享
    nginx 不带www到www域名的重定向
    配置电信网通双线双IP的解决办法
    Create a W3C validated anchor link with target=“_blank”
    Could not update ICEauthority file /home/username/.ICEauthority
    Can't load IA 32bit .dll on a AMD 64bit platform
  • 原文地址:https://www.cnblogs.com/ljl150/p/11694429.html
Copyright © 2011-2022 走看看