Java执行机制

Java 源码编译—–javac将java源码编译为class

java源文件(.java)=>分析和输入到符号表=>注解(annotation)处理=>语义分析和生成class文件

class文件的内容

class文件的内容如下:

  • 结构信息:class文件格式版本号等信息=>所以高版本的jdk生成的.class文件低版本的jre无法运行,反之可以运行
  • 元数据:类继承、接口实现、属性和方法的声明、常量池等信息
    *方法信息:Java源文件中语句、表达式对应的信息,包括:字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试用符号信息

例子:

// Hello.java
public class Hello {
    public static void sayHi() {
        System.out.println("Hello World!");
    }
    public static int add(int x, int y) {
        return x + y;
    }
    public static void main(String[] args) {
        sayHi();
        System.out.println(add(4, 5));
    }
}

使用javac -g Hello.java(使用javac Hello.java也可,但调试信息更少)产生Hello.class文件

再使用javap -c Hello可以反编译字节码,输出如下:

// Compiled from "Hello.java"
public class Hello {
public Hello();
    Code:
       0: aload_0
       1: invokespecial #1
       // Method java/lang/Object."":()V
       4: return        

  public static void sayHi();
    Code:
       0: getstatic     #2
       // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3
       // String Hello World!
       5: invokevirtual #4
       // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return        

  public static int add(int, int);
    Code:
       0: iload_0
       1: iload_1
       2: iadd
       3: ireturn       

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #5
       // Method sayHi:()V
       3: getstatic     #2
       // Field java/lang/System.out:Ljava/io/PrintStream;
       6: iconst_4
       7: iconst_5
       8: invokestatic  #6
       // Method add:(II)I
      11: invokevirtual #7
      // Method java/io/PrintStream.println:(I)V
      14: return
}

类执行机制

  • 字节码解释执行
    jvm有一套中间码,如invokestatic(调用static方法)、invokevirtual(调用对象实例方法)、invokeinterface(调用接口的方法)和invokespecial(调用private方法和方法)等。
    因此,jvm可以把这写中间码的指令解释执行,就像类似于脚本语言执行。只不过脚本语言执行的源文件是可读的文本文件,
    而jvm解释执行执行的是不可读的.class文件。

  • 字节码编译执行
    解释执行效率低,所以jvm可以在运行时把.class文件编译成机器码执行,这就是JIT编译。
    所谓的Hotspot 就是执行时对执行频率高的代码编译执行,执行频率低的代码解释执行。