第7章 方法调用和返回,类初始化

调用的角度来看,方法可以分为两类:

  • 静态方法(或者类方法)invoke static
    静态方法是静态绑定的,最终调用的是哪个方法在编译期就已经确定,调用前会检查类有没有初始化,没初始化先初始化再调用
  • 实例方法。invoke special``invoke interface invoke virtual:
    支持动态绑定,最终要调用哪个方法可能要推迟到运行期才能知道

实现的角度来看,方法可以分为三类:

  • 没有实现(也就是抽象方法)、
  • 用Java语言(或者JVM上的其他语言,如Groovy和Scala等)实现
  • 用本地语言(如C或者C++)实现。

在Java 8之前,接口只能包含抽象方法。为了实现Lambda表达式,Java 8放宽了这一限制,在接口中也可以定义静态方法和默认方法。

本章不考虑接口的静态方法和默认方法,

在Java 7之前,Java虚拟机规范一共提供了4条方法调用指令

  • invoke static: 调用静态方法。
  • invoke special: 调用无须动态绑定的实例方法:构造函数、私有方法、超类方法。
    剩下的情况则属于动态绑定
  • invoke interface: 对接口调用
  • invoke virtual:一般的实例方法

方法调用过程:

    1. 拿到方法引用
      用操作数去[运行时常量池]拿到 方法引用
      methodref = (MethodRef)frame.method.class.runtimeConstantPool.getConstant(操作数);
methodref {
  String className;
  String methodName;
  String methodDescriptor;
}
  • 2.找到方法
    根据方法引用的3维坐标 ,找到要调用的method
method{
    int accessFlags ;
    String  name;
    String  descriptor;//从中能计算得到argSlotCount
    int maxStack;
    int maxLocals;
    byte[] code;
}

这个method不一定就是被调用的那个,几条调用指令的区别就在这Invokestatic等

  • 3.invoke方法
    给这个方法创建一个新的帧fram,localVars里面按次序放入参数(调用方法的帧会在OperandStack里面放好要传的参数,invokeXXX指令之前的指令会放好),推入Java虚拟机栈顶


    实例方法调用第一个参数是this

return

弹出执行完方法非栈帧,它的OperandStack顶是方法执行结果,压入调用这个栈帧的栈帧

thread = frame.getThread();
endFrame = thread.popFrame();
waitReturnFrame= thread.currentFrame();
result = endFrame .getOperandStack().pop();
waitReturnFrame.getOperandStack().push(result );

类初始化

就是执行类的静态变量初始化语句和静态块的, 编译会给加一个,没有静态初始化语句就没有。
检查有没有执行如果没有执行就先执行clinit,执行完再回来执行
触发:

 if (class.initStarted ){
            frame.revertNextPC();//pc恢复本指令执行以前 初始化以后会再进本指令运行
            init(frame.thread, class);
            return;
 }

以下这些时间要检查:

  • new指令创建类实例
  • putstatic、getstatic
  • invokestatic
  • 执行某些反射操作时。

初始化,继承链往上走 每个都要初始化

 for (Class aClass =class;aClass.getSuperClass()==null;aClass1=aClass.getSuperClass()) {
            Method initMethod= aClass .getStaticMethod("", "()V");;
            if(initMethod!=null){
                thread.pushFrame(initMethod);//都要先执行父类初始化
            }
        }

你可能感兴趣的:(第7章 方法调用和返回,类初始化)