Java字节码中的方法调用
invokestatic,用于static修饰的方法。任何时候调用的时候只需要类名+方法名即可,无需new。JVM直接将其映射到方法区,执行速度极快。当该方法需要参数的时候,invokestatic会使用命令将参数从栈中弹出,传递给invokestatic。
invokevirtual,用于public和protected修饰而没有static修饰的方法。在invokevirtual之前,总会有两条命令,astore(从栈中弹出对象引用,然后将其存到相应位置的局部变量中) & aload(将对象引用从局部变量表中取出,压栈), 是因为在调用invokevirtual时,会从栈里弹出两个参数,是objectref和我们自定义的参数列表。objectref就是this,因为非static方法不是直接从方法区用的,所以得匹配所属类,是默认的隐式参数,无法从代码层指定objectref。参数列表就是我们自定义的传入参数了。
invokespecial,用于本类的构造方法的初始化<init>和super修饰的方法以及非static修饰的private方法。
invokeinterface:用于接口调用的情况,速度是最慢的,因为接口不知道类的具体信息,所以每次运行前得遍历整个类(校验+匹配),而invokevirtual是直接关联类的,方法偏移量是固定的。