zoukankan      html  css  js  c++  java
  • 方法调用

    方法调用

    确定被调用方法的版本

    包括解析调用方法分派

    解析调用

    对于在那些"编译器可知,运行期不可变"的方法,主要包括静态方法和私有方法。前者与类型直接关联,后者外部不可访问,决定了它们都不能通过继承或者别的方式重写出其它版本,适合在类加载阶段进行解析。

    对应的字节码指令:invokestatic,invokespecial

    解析调用是静态的过程,在编译器完全确定,在类加载阶段就会把涉及的符号引用全部转化为直接引用,不必延后到运行期再确定。方法调用还有另一种形式:分派,包括静态分派动态分派

    分派

    分派体现了多态的特性

    静态分派

    静态分派的主要体现就是方法重载

    • 方法重载是根据静态类型确定方法版本的,具体来说,子类对象可以指向父类引用,那么等号左边的父类就是静态类型,在编译器已知,而等号右边的子类是实际类型,在运行期才能确定下来。

    • 静态分派发生在编译阶段。编译器虽然能确定方法的重载版本,但很多情况下并不是唯一的,在存在多个合适版本的情况下,会选择最合适的版本。重载方法的参数类型可以转化的顺序:自动类型转换——>包装类——>接口——>父类——>变长参数

    public class Test {
        static class Human{
        }
        static class Man extends Human{
        }
        static class Woman extends Human{
        }
        public void sayHello(Human human){
            System.out.println("hello,gay.");
        }
        public void sayHello(Man man){
            System.out.println("hello,man.");
        }
        public void sayHello(Woman woman){
            System.out.println("hello,woman.");
        }
        public static void main(String[] args) {
            Test tx=new Test();
            Human man=new Man();
            Human woman=new Woman();
            tx.sayHello(man);
            tx.sayHello(woman);
        }
    ​
        /*
        hello,gay.
        hello,gay.
        */

    动态分派

    动态分派的主要体现是方法重写

    这种多态性的根源在于虚方法调用指令invokevirtual的执行逻辑,invokevirtual第一步就是确定操作数栈顶第一个元素所指向对象的实际类型,也就是在运行期确定方法接收者的实际类型。

    • 方法重写是根据方法接受者的实际类型来选择方法版本的

    • 字段没有多态性,哪个类的方法访问某个名字的字段时,改名字指的就是这个类能看到的那个字段。

      public class Polymorphism {
          static class Human{
              public void show(){
                  System.out.println("hello,guy");
              }
          }
          static class Man extends Human{
              public void show(){
                  System.out.println("hello,man");
              }
          }
          static class Woman extends Human{
              public void show(){
                  System.out.println("hello,woman");
              }
          }
      ​
          public static void main(String[] args) {
              Human man=new Man();
              man.show();//hello,man
              Human woman=new Woman();
              woman.show();// hello,woman
              man=new Woman();
              man.show();// hello,woman
          }
      }
      

        

  • 相关阅读:
    最长上升子序列(矩形嵌套)
    中国剩余定理模板poj1006
    POJ 2891 扩展欧几里德
    2015多校联赛第三场(部分题解)
    树链剖分
    深度理解链式前向星
    POJ 1228 Grandpa's Estate(凸包)
    旋转卡壳(一)
    最小圆覆盖 hdu 3007
    半平面求交 模板
  • 原文地址:https://www.cnblogs.com/learnjavajava/p/14900003.html
Copyright © 2011-2022 走看看