方法调用

方法调用

确定被调用方法的版本

包括解析调用方法分派

解析调用

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

对应的字节码指令: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
        }
    }
    

      

posted @ 2021-06-18 16:19  keepkeep  阅读(60)  评论(0编辑  收藏  举报