“二哥,看了 Hello World 的代码后,我很好奇,它是怎么在 IDEA 的 Run 面板里打印出‘三妹,少看手机少打游戏,好好学,美美哒’呢?”三妹咪了一口麦香可可奶茶后对我说。
“三妹,我们通常把 Java 代码执行的过程分为编译期和运行时,弄清楚这两个阶段就知道原因了。”我微笑着对三妹说,“对于一个 Java 程序员来说,写了那么久的代码,总要搞清楚自己写的 Java 代码到底是怎么运行起来的。这个问题在面试的时候也经常会被问到。”
一起来看下吧。
编译期
贴一下 HelloWorld 这段代码:
/**
* @author 微信搜「沉默王二」,回复关键字 PDF
*/
public class HelloWorld {
public static void main(String[] args) {
System.out.println("三妹,少看手机少打游戏,好好学,美美哒。");
}
}
点击 IDEA 工具栏中的锤子按钮(Build Project,编译整个项目,通常情况下,并不需要主动编译,IDEA 会自动帮我们编译),如下图所示。
这时候,就可以在 src 的同级目录 target 下找到一个名为 HelloWorld.class 的文件。
如果找不到的话,在目录上右键选择「Reload from Disk,从磁盘上重新加载」,如下图所示:
可以双击打开它,看到如下所示的内容。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.itwanger.five;
public class HelloWorld {
public HelloWorld() {
}
public static void main(String[] args) {
System.out.println("三妹,少看手机少打游戏,好好学,美美哒。");
}
}
IDEA 默认会用 Fernflower 这个反编译工具将字节码文件(后缀为 .class 的文件,也就是 Java 源代码编译后的文件)反编译为我们可以看得懂的 Java 源代码。
但实际上,字节码文件并不是这样的,它包含了 JVM 执行的指令,还有类的元数据信息,如类名、方法和属性等。如果用 「show bytecode」打开字节码文件的话,它是下面这样子的:
// class version 58.0 (58)
// access flags 0x21
public class com/itwanger/five/HelloWorld {
// compiled from: HelloWorld.java
// access flags 0x1
public <init>()V
L0
LINENUMBER 6 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L1
LOCALVARIABLE this Lcom/itwanger/five/HelloWorld; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x9
public static main([Ljava/lang/String;)V
L0
LINENUMBER 8 L0
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\u4e09\u59b9\uff0c\u5c11\u770b\u624b\u673a\u5c11\u6253\u6e38\u620f\uff0c\u597d\u597d\u5b66\uff0c\u7f8e\u7f8e\u54d2\u3002"
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L1
LINENUMBER 9 L1
RETURN
L2
LOCALVARIABLE args [Ljava/lang/String; L0 L2 0
MAXSTACK = 2
MAXLOCALS = 1
}
是不是就有点看不懂了?我第一次看到这段内容的时候也很头大,不过不要担心,后面我们再一块深入研究,这里就提前感受一下 bytecode(也就是字节码)的魅力(😂)。
怎么查看 bytecode 呢?
可以通过 IDEA 菜单栏中的「View」→「Show Bytecode」查看,如下图所示。
这个 bytecode 可以直译为字节码。
字节码并不是机器码,操作系统无法直接识别,需要在操作系统上安装不同版本的 JVM 来识别。
通常情况下,我们只需要安装不同版本的 JDK(Java Development Kit,Java 开发工具包)就行了,它里面包含了 JRE(Java Runtime Environment,Java 运行时环境),而 JRE 又包含了 JVM。
回复