一、办法调用指令阐明


简要介绍办法调用指令:

invokevirtual、invokeinterface、invokespecial、invokestatic、invokedynamic

简要办法调用介绍

invokevirtual指令

用于调用对象的实例办法,依据对象的理论类型进行分派(虚办法分派),反对多态。

这也是Java语言中最常见的办法分派形式。

invokeinterface指令

用于调用接口办法,它会在运行时搜寻由特定对象所实现的这个接口办法,并找出适宜的办法进行调用。

invokespecial指令

用于调用一些须要非凡解决的实例办法,包含实例初始化办法(结构器)、公有办法和父类办法。这些办法都是动态类型绑定的,不会在调用时进行动静派发。

invokestatic指令

用于调用命名类中的类办法(static办法)。这是动态绑定的。

invokedynamic指令

调用动静绑定的办法,这个是JDK 1.7后新退出的指令。

用于在运行时动静解析出调用点限定符所援用的办法,并执行该办法。后面4条调用指令的分派逻辑都固化在java虚拟机外部,而invokedynamic指令的分派逻辑是由用户所设定的疏导办法决定的。

二、通过示例代码来领会办法调用指令


接下来咱们通过示例代码拉领会对应的办法指令,看看会有什么不一样?

public class MethodInvokeReturnTest {        //办法调用指令:invokespecial    public void invoke1(){            //状况1:类实例的结构器办法:<init>()        Date date = new Date();        Thread t1 = new Thread();                //状况2:父类的办法        super.toString();                //状况3:公有办法        methodPrivate();    }        private void methodPrivate(){        }}

接下来咱们把以后的代码编译一下,看看具体的字节码是怎么形容以后办法的?

如果咱们将以后公有办法methodPrivate改为public润饰的办法就会产生扭转(可重写)

接下来咱们通过示例代码拉领会下一个办法指令,看看会有什么不一样?

public class MethodInvokeReturnTest {        //办法调用指令:invokestatic    public void invoke2(){        methodstatic();    }        public static void methodStatic(){        }}

把以后的代码编译一下,看看具体的字节码是怎么形容以后办法的?

接下来咱们通过示例代码拉领会下一个办法指令,看看会有什么不一样?

public class MethodInvokeReturnTest {        //办法调用指令:invokevirtual    public void invoke4(){        system.out.println( "he1lo");        Thread t1 = null;        t1.run();    }}

把以后的代码编译一下,看看具体的字节码是怎么形容以后办法的?

接下来咱们通过示例代码拉领会下一个办法指令,看看会有什么不一样?

public class MethodInvokeReturnTest {        //办法调用指令:invokeinterface    public void invoke3(){            Thread t1 = new Thread();        ((Runnable)t1).run();                Comparable<Integer> com = null;        com.compareTo(123);    }}

把以后的代码编译一下,看看具体的字节码是怎么形容以后办法的?

那么针对于接口里的静态方法与非静态方法,调用之后又会是什么状况呢?

interface AA{        public static void method1(){}        public default void method2(){}}class BB implements AA{}public class InterfaceMethodTest{    public static void main( string[] args){        AA aa = new BB();        aa.method2();        AA.method1();    }}

把以后的代码编译一下,看看具体的字节码是怎么形容以后办法的?

三、通过示例代码来领会办法返回指令


办法调用完结前,须要进行返回。办法返回指令是依据返回值的类型辨别的。

当咱们返回值是boolean、byte、char、short和int类型采纳ireturn示意

当咱们返回值是float类型采纳freturn示意

当咱们返回值是double类型采纳dreturn示意

当咱们返回值是援用型采纳areturn示意

还有一条return指令供申明为void的办法、实例初始化办法以及类和接口的类初始化办法应用。

示例指令解说

通过ireturn指令,将以后函数操作数栈的顶层元素弹出,并将这个元素压入调用者函数的操作数栈中〈因为调用者十分关怀函数的返回值),所有在以后函数操作数栈中的其余元素都会被抛弃。

如果以后返回的是synchronized办法,那么还会执行一个隐含的monitorexit指令,退出临界区

最初,会抛弃以后办法的整个帧,复原调用者的帧,并将控制权转交给调用者。

接下来咱们通过示例代码拉领会对应的办法指令,看看是怎么样的?

public class MethodInvokeReturnTest {        //办法的返回指令    public int returnInt(){        int i = 50;        return i;    }}

把以后的代码编译一下,看看具体的字节码是怎么形容以后办法的?

接下来咱们通过示例代码拉领会其余办法返回指令,看看会有什么不一样?

public class MethodInvokeReturnTest {        //办法的返回指令    public double returnDouble(){        return 0.0;    }    public string returnstring(){        return "hello,wor1d" ;    }    public int[] returnArr(){        return nu1l;    }    public float returnFloat(){        int i = 10;        return i;    }    public byte returnByte(){        return 0;    }}

把以后的代码编译一下,看看具体的字节码是怎么形容以后办法的?