美文网首页
分派的简单理解

分派的简单理解

作者: 听歌闭麦开始自闭 | 来源:发表于2019-02-18 20:08 被阅读0次

invokevirtual字节码

在具体举例描述之前先描述invokevirtual字节码工作过程

找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C。
在类型C中找到与常量中的描述符和简单名称都相符的方法。
     如果找到则进行访问权限的校验。
         如果通过则返回这个方法的直接引用,查询结束;
         如果不通过,则返回java.lang.IllegalAccessError异常。
    否则,按继承关系从下向上对C的各个父类进行第2步操作。
如果没有找到合适的方法,抛出AbstractMethodError异常。

以下判断均基于该字节码


invokevirtual字节码.png

分派

Java语言的静态分派属于多分派类型;Java语言的动态分派属于单分派类型

静态分派是由编译器指定的,编译器虽然能确定出方法的重载版本,但在很多情况下这个重载版本并不是"唯一的"。
有显式的静态类型时,通过静态类型确认执行哪个重载方法
没有显式的静态类型时,只能通过语言上的规则去理解和推断

类型变化简单描述
示例代码: Human man = new Man();  
// "Human"称为变量的静态类型/外观类型   “Man” 则称为变量的实际类型

// 实际类型变化
Human man = new Man();
man = new Woman();

// 静态类型变化
sr.sayHello((Man) man);
sr.sayHello((Woman) man)

静态分派

可以理解为方法的入参与静态分派有关,静态分派决定了在方法重载时使用哪个运行。

public class StaticDispatch {

    public void sayHello(Human guy) { System.out.println(1); }

    public void sayHello(Man guy) { System.out.println(2); }

    public void sayHello(Woman guy) { System.out.println(3); }

    // 输出结果为 1   2   1   3
    public static void main(String[] args) {
        Human man = new Man();
        Human woman = new Woman();
        StaticDispatch sd = new StaticDispatch();
        sd.sayHello(man);
        sd.sayHello((Man) man);
        sd.sayHello(woman);
        sd.sayHello((Woman) woman);
    }
}

abstract class Human {}

class Man extends Human {}

class Woman extends Human {}
静态分派代码字节码.png

动态分派

invokevirtual字节码含义的体现,动态分派决定了在方法重写时使用哪个运行。

public class DynamicDispatch {
    public static void main(String[] args) {
        Human man = new Man();
        man.sayHello();
        man = new Woman();
        man.sayHello();

        Human woman = new Woman();
        woman.sayHello();
    }
}

abstract class Human {
    protected abstract void sayHello();
}

class Man extends Human {

    @Override
    protected void sayHello() { System.out.println("man say Hello!"); }
}

class Woman extends Human {

    @Override
    protected void sayHello() { System.out.println("woman say Hello!"); }
}
动态分派代码字节码.png

Java 自带类型的方法重载

这个示例就是没有显式的静态类型,所以只能通过语言上的规则去理解和推断

测试方法是:以char-> int -> long -> float -> double -> 包装类 ->Serializable -> Object -> 可变长参数的顺序尝试注释目标方法,然后运行看输出结果。
如果在idea中则不需要运行测试,被调用的方法会高亮,通过观察就可以知道结果。

public class Overload {
    public static void sayHello(Object arg) {
        System.out.println("Object");
    }
    public static void sayHello(int arg) {
        System.out.println("int");
    }
    public static void sayHello(long arg) {
        System.out.println("long");
    }
    public static void sayHello(float arg) {
        System.out.println("float");
    }
    public static void sayHello(double arg) {
        System.out.println("double");
    }
    public static void sayHello(char arg) {
        System.out.println("char");
    }
    public static void sayHello(char... arg) {
        System.out.println("char");
    }
    public static void sayHello(Character arg) {
        System.out.println("Character");
    }
    public static void sayHello(Integer arg) {
        System.out.println("Character");
    }
    public static void sayHello(Serializable arg) {
        System.out.println("Serializable");
    }

    public static void main(String[] args) {
        sayHello('c');
    }
}

相关文章

  • 分派的简单理解

    invokevirtual字节码 在具体举例描述之前先描述invokevirtual字节码工作过程 以下判断均基于...

  • 多态->分派

    摘抄深入理解java虚拟机目标 分派包括: 静态分派与动态分派两种类型, 静态分派的使用场景为重载, 动态分派使用...

  • 怎样理解Java的方法分派

    初级:多态,虚方法表的认识中级:对编译和运行时的理解和认识高级:对Java语言规范和运行机制的深入认识高级:横向对...

  • 重载选择(静态分派),解析调用与动态分派(多态)的特性研究

    根据周志明《深入理解java虚拟机》所述,国内把重载方法的选择过程叫做静态分派,除此之外是解析调用和动态分派。个人...

  • Java静态分派、动态分派、双重分派

    动态分派和静态分派机制是java多态的实现原理。 静态分派(方法重载) 静态分派机制最典型的代码: 这段代码执行完...

  • iOS GCD开发运用场景

    (一)、线程的概念和与生命周期 进程:可以简单理解为进程为一个应用程序 线程:是CPU调度和分派的基本单位 下图是...

  • 0052—每日一记作业

    1请分析不同的股息分派原则和股价的关系。 股息分派原则:保守股息政策:简单的权宜之计实现支付,数年后股票价格将会有...

  • Java方法分派

    静态分派 - 方法重载分派编译期确定根据调用者的声明类型和方法参数类型分派 动态分派 - 方法重写分派运行时确定根...

  • (JVM)Java虚拟机:静态分派 & 动态分派 原理解

    前言 了解 行为方法分派 有利于在行为分派时时进行一些功能操作 本文全面讲解行为分派的类型:静态 & 动态行为分派...

  • java方法调用-单分派与多分派

    根据分派基于多少种宗量(方法的接收者与方法的参数统称为方法的宗量),可以将分派划分为单分派和多分派两种。单分派是根...

网友评论

      本文标题:分派的简单理解

      本文链接:https://www.haomeiwen.com/subject/wcyzeqtx.html