zoukankan      html  css  js  c++  java
  • jvm是怎样调用方法的

    jvm内部有五种调用方法的指令

    invokeinterface	用以调用接口方法,在运行时搜索一个实现了这个接口方法的对象,找出适合的方法进行调用。(Invoke interface method)
    invokevirtual	指令用于调用对象的实例方法,根据对象的实际类型进行分派(Invoke instance method; dispatch based on class)
    invokestatic	用以调用类方法(Invoke a class (static) method )
    invokespecial	指令用于调用一些需要特殊处理的实例方法,包括实例初始化方法、私有方法和父类方法。(Invoke instance method; special handling for superclass, private, and instance initialization method invocations )
    invokedynamic	JDK1.7新加入的一个虚拟机指令,相比于之前的四条指令,他们的分派逻辑都是固化在JVM内部,而invokedynamic则用于处理新的方法分派:它允许应用级别的代码来确定执行哪一个方
    invokestatic和invokespecial是在编译器确定的,他们适用于不会发生重写的情况
    invokevirtual和invokeinterface	是虚方法,这两个指令在调用时,通过一张方法表来调用。

    看两个类

    public class Animal {
        protected void sleep(){
            System.out.println("动物能睡觉");
        }
    }
    
    
    
    
    
    public class Bird extends Animal implements Fly {
        @Override
        protected void sleep() {
            System.out.println("鸟会睡觉");
        }
    
        @Override
        public void fly() {
            System.out.println("鸟会飞");
        }
    
        public static void print() {
            System.out.println("这是鸟");
        }
    }
    
    
    

    两个类对应的方法表

    animal的方法表

    0
    sleep

    bird方法表

    0sleep
    1 fly

    如果重写父类的方法,父类方法的index和子类的一致,方便查找。

    由上可知,使用继承或实现会让程序变慢,因为需要查方法表,但是没有必要因为慢而放弃面向对象良好的设计,因为这个时间很短并且jvm还有针对虚方法的优化,内联缓存。

    内联缓存举个例子来说

    Animal animal = new Bird();

    animal.sleep();

    这个时候jvm缓存下bird对象和sleep方法,下次bird对象想要调用sleep方法时,缓存里存了bird的方法就不用去查表了。

  • 相关阅读:
    poj_2352树状数组
    poj_2187凸包,暴力解法
    zoj_3735,dp,长沙站j题
    hdu_1698线段树成段更新
    poj_2828线段树,逆序插入
    poj_3371
    poj_3071概率dp
    hdu_2191多重背包
    poj_1185状压dp
    css-margin
  • 原文地址:https://www.cnblogs.com/zhandouBlog/p/10350049.html
Copyright © 2011-2022 走看看