千家信息网

JVM真香系列之如何学习Java文件到.Class文件

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容主要讲解"JVM真香系列之如何学习Java文件到.Class文件",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"JVM真香系列之如何学习Java文件
千家信息网最后更新 2026年11月02日JVM真香系列之如何学习Java文件到.Class文件

本篇内容主要讲解"JVM真香系列之如何学习Java文件到.Class文件",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"JVM真香系列之如何学习Java文件到.Class文件"吧!

什么是JVM

JVM 全称 Java Virtual Machine,也就是我们耳熟能详的 Java 虚拟机。它能识别 .class后缀的文件,并且能够解析它的指令,最终调用操作系统上的函数,完成我们想要的操作。

可能有部分小伙伴学习过C++,C++开发出来的程序,编译成二进制文件后,就可以直接执行了,操作系统是能够识别的。

但是咱们开的的Java程序就不一样了,使用javac命令编译出来的的.class文件之后,操作系统是不能识别的,需要对应JVM去做一个转换后,操作系统才能识别。

我们为什么不能像 C++ 一样,直接在操作系统上运行编译后的二进制文件呢?而非要搞一个处于程序与操作系统中间层的虚拟机呢?

这就是 JVM的过人之处了。大家都知道,Java 是一门抽象程度特别高的语言,提供了自动内存管理等一系列的特性。这些特性直接在操作系统上实现是不太可能的,所以就需要JVM 进行做一系列的转换。

大家一开始学Java的时候,就知道有个Write Once, Run Everywhere。就是我们编写了一个java文件经过编译成.class文件后,可以在各种系统中进行运行。

其实这里是有个前提的,我们需要在对应操作系统中安装对应的JVM,然后我们的.class文件就能运行了。

比如:Windows操作系统有对应的JDK安装版本、Linux也有对应的JDK安装版本等。

认识JDK

Java Development Kit (JDK) 是Sun公司(已被Oracle收购)针对Java开发员的软件开发工具包。自从Java推出以来,JDK已经成为使用最广泛的Java SDK(Software development kit)。

经非官方调查,目前JDK8是使用者最多的版本。

JDK14将在4月和7月收到安全更新,然后由9月到期的非LTS版本的JDK 15取代。JDK14包括16项新功能,例如JDK Flight Recorder事件流,模式匹配和开关表达式等特征。

从JDK9之后,Oracle采用了新的发布周期:每6个月发布一个版本,每3年发布一个LTS版本。JDK14是继JDK9之后发布的第四个版本, 该版本为非LTS版本,最新的LTS版本为JDK11。

下面是JDK版本情况


这个混个眼熟就行,随时关注JDK版本更新和新特性。

官网地址:https://www.oracle.com/java/

关于JDK安装这里就省略。

JDK、JRE、JVM的关系

上面已经说过JDK和JVM的相关概念,

JRE全程Java Runtime Environment,是运行基于Java语言编写的程序所不可缺少的运行环境。也是通过它,Java的开发者才得以将自己开发的程序发布到用户手中,让用户使用。

三者到底是什么关系呢?

关于三者关系请看官网

https://docs.oracle.com/javase/8/docs/index.html

JDK中包含JRE,也包括JDK,而JRE也包括JDK。范围关系:JDK>JRE>JVM

".java"文件到".class"文件

`javac`命令

编写一个HelloWorld.java文件

内容就是一个Java入门

public class HelloWorld {     public static void main(String[] args) {         System.out.println("Hello world");     } }

打开CMD,进入当前目录,使用命令

javac HelloWorld.java

就编译出HelloWorld.class

编译过程

这个javac命令过程到底干了些什么呢?

javac背后大致做了这些操作


这个流程

1、词法分析

读取源代码,一个字节一个字节的读取,找出其中我们定义好的关键字(如Java中的if、else、for、while等关键词,识别哪些if是合法的关键词,哪些不是),这就是词法分析器进行词法分析的过程,其结果是从源代码中找出规范化的Token流。

2、语法分析

通过语法分析器对词法分析后Token流进行语法分析,这一步检查这些关键字组合再一次是否符合Java语言规范(如在if后面是不是紧跟着一个布尔判断表达式),词法分析的结果是形成一个符合Java语言规范的抽象语法树。

3、语义分析

通过语义分析器进行语义分析。语音分析主要是将一些难懂的、复杂的语法转化成更加简单的语法,结果形成最简单的语法(如将foreach转换成for循环 ,好有注解等),最后形成一个注解过后的抽象语法树,这个语法树更为接近目标语言的语法规则。

4、生成字节码

通过字节码生产器生成字节码,根据经过注解的语法抽象树生成字节码,也就是将一个数据结构转化为另一个数据结构。最后生成我们想要的.class文件。

使用十六进制查看class文件内容

我只用的是Notepad++,选中文本→插件→Converter→ASCII->HEX

class文件的开头就是

CAFEBABE

想要学习这里的十六进制的字节码的含义可以参考

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html

javap查看class文件内容

javap是 Java class文件分解器,可以反编译(即对javac编译的文件进行反编译),也可以查看java编译器生成的字节码。

新建一个User.java源文件,经过javac编译后,生成User.classs。

package com.tian.demo.test;  public class User {     private int age = 22;     private String name = "tian";      public int addAge() {         return age = age + 1;     }      public static void main(String[] args) {      } }

使用javap命令

javap -v User.class >log.txt

打开log.txt

Classfile /D:/workspace/new/demo/src/main/java/com/tian/demo/test/User.class   Last modified 2020-11-5; size 441 bytes   MD5 checksum 2fa72d3f53bd9f138e0bfae82aba67e3   Compiled from "User.java" public class com.tian.demo.test.User   minor version: 0   major version: 52   flags: ACC_PUBLIC, ACC_SUPER Constant pool:    #1 = Methodref          #6.#21         // java/lang/Object."":()V    #2 = Fieldref           #5.#22         // com/tian/demo/test/User.age:I    #3 = String             #23            // tian    #4 = Fieldref           #5.#24         // com/tian/demo/test/User.name:Ljava/lang/String;    #5 = Class              #25            // com/tian/demo/test/User    #6 = Class              #26            // java/lang/Object    #7 = Utf8               age    #8 = Utf8               I    #9 = Utf8               name   #10 = Utf8               Ljava/lang/String;   #11 = Utf8                  #12 = Utf8               ()V   #13 = Utf8               Code   #14 = Utf8               LineNumberTable   #15 = Utf8               addAge   #16 = Utf8               ()I   #17 = Utf8               main   #18 = Utf8               ([Ljava/lang/String;)V   #19 = Utf8               SourceFile   #20 = Utf8               User.java   #21 = NameAndType        #11:#12        // "":()V   #22 = NameAndType        #7:#8          // age:I   #23 = Utf8               tian   #24 = NameAndType        #9:#10         // name:Ljava/lang/String;   #25 = Utf8               com/tian/demo/test/User   #26 = Utf8               java/lang/Object {   public com.tian.demo.test.User();     descriptor: ()V     flags: ACC_PUBLIC     Code:       stack=2, locals=1, args_size=1          0: aload_0          1: invokespecial #1                  // Method java/lang/Object."":()V          4: aload_0          5: bipush        22          7: putfield      #2                  // Field age:I         10: aload_0         11: ldc           #3                  // String tian         13: putfield      #4                  // Field name:Ljava/lang/String;         16: return       LineNumberTable:         line 3: 0         line 4: 4         line 5: 10    public int addAge();     descriptor: ()I     flags: ACC_PUBLIC     Code:       stack=3, locals=1, args_size=1          0: aload_0          1: aload_0          2: getfield      #2                  // Field age:I          5: iconst_1          6: iadd          7: dup_x1          8: putfield      #2                  // Field age:I         11: ireturn       LineNumberTable:         line 8: 0    public static void main(java.lang.String[]);     descriptor: ([Ljava/lang/String;)V     flags: ACC_PUBLIC, ACC_STATIC     Code:       stack=0, locals=1, args_size=1          0: return       LineNumberTable:         line 13: 0 } SourceFile: "User.java"
  • 魔数与class文件版本

  • 常量池

  • 访问标志

  • 类索引、父类索引、接口索引

  • 字段表集合

  • 方法表集合

  • 属性表集合

然后JVM就可以读取这个User.class文件进行解析等一系列的操作。

以上就是我们的Java文件到class文件。

IT技术分享社区

个人博客网站:https://programmerblog.xyz认识JVM

什么是JVM

JVM 全称 Java Virtual Machine,也就是我们耳熟能详的 Java 虚拟机。它能识别 .class后缀的文件,并且能够解析它的指令,最终调用操作系统上的函数,完成我们想要的操作。

可能有部分小伙伴学习过C++,C++开发出来的程序,编译成二进制文件后,就可以直接执行了,操作系统是能够识别的。

但是咱们开的的Java程序就不一样了,使用javac命令编译出来的的.class文件之后,操作系统是不能识别的,需要对应JVM去做一个转换后,操作系统才能识别。

我们为什么不能像 C++ 一样,直接在操作系统上运行编译后的二进制文件呢?而非要搞一个处于程序与操作系统中间层的虚拟机呢?

这就是 JVM的过人之处了。大家都知道,Java 是一门抽象程度特别高的语言,提供了自动内存管理等一系列的特性。这些特性直接在操作系统上实现是不太可能的,所以就需要JVM 进行做一系列的转换。

大家一开始学Java的时候,就知道有个Write Once, Run Everywhere。就是我们编写了一个java文件经过编译成.class文件后,可以在各种系统中进行运行。

其实这里是有个前提的,我们需要在对应操作系统中安装对应的JVM,然后我们的.class文件就能运行了。

比如:Windows操作系统有对应的JDK安装版本、Linux也有对应的JDK安装版本等。


认识JDK

Java Development Kit (JDK) 是Sun公司(已被Oracle收购)针对Java开发员的软件开发工具包。自从Java推出以来,JDK已经成为使用最广泛的Java SDK(Software development kit)。

经非官方调查,目前JDK8是使用者最多的版本。

JDK14将在4月和7月收到安全更新,然后由9月到期的非LTS版本的JDK 15取代。JDK14包括16项新功能,例如JDK Flight Recorder事件流,模式匹配和开关表达式等特征。

从JDK9之后,Oracle采用了新的发布周期:每6个月发布一个版本,每3年发布一个LTS版本。JDK14是继JDK9之后发布的第四个版本, 该版本为非LTS版本,最新的LTS版本为JDK11。

下面是JDK版本情况


这个混个眼熟就行,随时关注JDK版本更新和新特性。

官网地址:https://www.oracle.com/java/

关于JDK安装这里就省略。

JDK、JRE、JVM的关系

上面已经说过JDK和JVM的相关概念,

JRE全程Java Runtime Environment,是运行基于Java语言编写的程序所不可缺少的运行环境。也是通过它,Java的开发者才得以将自己开发的程序发布到用户手中,让用户使用。

三者到底是什么关系呢?

关于三者关系请看官网

https://docs.oracle.com/javase/8/docs/index.html


JDK中包含JRE,也包括JDK,而JRE也包括JDK。范围关系:JDK>JRE>JVM

".java"文件到".class"文件

`javac`命令

编写一个HelloWorld.java文件


内容就是一个Java入门

public class HelloWorld {     public static void main(String[] args) {         System.out.println("Hello world");     } }

打开CMD,进入当前目录,使用命令

javac HelloWorld.java

就编译出HelloWorld.class

编译过程

这个javac命令过程到底干了些什么呢?

javac背后大致做了这些操作


这个流程


1、词法分析

读取源代码,一个字节一个字节的读取,找出其中我们定义好的关键字(如Java中的if、else、for、while等关键词,识别哪些if是合法的关键词,哪些不是),这就是词法分析器进行词法分析的过程,其结果是从源代码中找出规范化的Token流。

2、语法分析

通过语法分析器对词法分析后Token流进行语法分析,这一步检查这些关键字组合再一次是否符合Java语言规范(如在if后面是不是紧跟着一个布尔判断表达式),词法分析的结果是形成一个符合Java语言规范的抽象语法树。

3、语义分析

通过语义分析器进行语义分析。语音分析主要是将一些难懂的、复杂的语法转化成更加简单的语法,结果形成最简单的语法(如将foreach转换成for循环 ,好有注解等),最后形成一个注解过后的抽象语法树,这个语法树更为接近目标语言的语法规则。

4、生成字节码

通过字节码生产器生成字节码,根据经过注解的语法抽象树生成字节码,也就是将一个数据结构转化为另一个数据结构。最后生成我们想要的.class文件。

使用十六进制查看class文件内容

我只用的是Notepad++,选中文本→插件→Converter→ASCII->HEX


class文件的开头就是

CAFEBABE

想要学习这里的十六进制的字节码的含义可以参考

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html

javap查看class文件内容

javap是 Java class文件分解器,可以反编译(即对javac编译的文件进行反编译),也可以查看java编译器生成的字节码。

新建一个User.java源文件,经过javac编译后,生成User.classs。

package com.tian.demo.test;  public class User {     private int age = 22;     private String name = "tian";      public int addAge() {         return age = age + 1;     }      public static void main(String[] args) {      } }

使用javap命令

javap -v User.class >log.txt

打开log.txt

Classfile /D:/workspace/new/demo/src/main/java/com/tian/demo/test/User.class   Last modified 2020-11-5; size 441 bytes   MD5 checksum 2fa72d3f53bd9f138e0bfae82aba67e3   Compiled from "User.java" public class com.tian.demo.test.User   minor version: 0   major version: 52   flags: ACC_PUBLIC, ACC_SUPER Constant pool:    #1 = Methodref          #6.#21         // java/lang/Object."":()V    #2 = Fieldref           #5.#22         // com/tian/demo/test/User.age:I    #3 = String             #23            // tian    #4 = Fieldref           #5.#24         // com/tian/demo/test/User.name:Ljava/lang/String;    #5 = Class              #25            // com/tian/demo/test/User    #6 = Class              #26            // java/lang/Object    #7 = Utf8               age    #8 = Utf8               I    #9 = Utf8               name   #10 = Utf8               Ljava/lang/String;   #11 = Utf8                  #12 = Utf8               ()V   #13 = Utf8               Code   #14 = Utf8               LineNumberTable   #15 = Utf8               addAge   #16 = Utf8               ()I   #17 = Utf8               main   #18 = Utf8               ([Ljava/lang/String;)V   #19 = Utf8               SourceFile   #20 = Utf8               User.java   #21 = NameAndType        #11:#12        // "":()V   #22 = NameAndType        #7:#8          // age:I   #23 = Utf8               tian   #24 = NameAndType        #9:#10         // name:Ljava/lang/String;   #25 = Utf8               com/tian/demo/test/User   #26 = Utf8               java/lang/Object {   public com.tian.demo.test.User();     descriptor: ()V     flags: ACC_PUBLIC     Code:       stack=2, locals=1, args_size=1          0: aload_0          1: invokespecial #1                  // Method java/lang/Object."":()V          4: aload_0          5: bipush        22          7: putfield      #2                  // Field age:I         10: aload_0         11: ldc           #3                  // String tian         13: putfield      #4                  // Field name:Ljava/lang/String;         16: return       LineNumberTable:         line 3: 0         line 4: 4         line 5: 10    public int addAge();     descriptor: ()I     flags: ACC_PUBLIC     Code:       stack=3, locals=1, args_size=1          0: aload_0          1: aload_0          2: getfield      #2                  // Field age:I          5: iconst_1          6: iadd          7: dup_x1          8: putfield      #2                  // Field age:I         11: ireturn       LineNumberTable:         line 8: 0    public static void main(java.lang.String[]);     descriptor: ([Ljava/lang/String;)V     flags: ACC_PUBLIC, ACC_STATIC     Code:       stack=0, locals=1, args_size=1          0: return       LineNumberTable:         line 13: 0 } SourceFile: "User.java"
  • 魔数与class文件版本

  • 常量池

  • 访问标志

  • 类索引、父类索引、接口索引

  • 字段表集合

  • 方法表集合

  • 属性表集合

然后JVM就可以读取这个User.class文件进行解析等一系列的操作。


以上就是我们的Java文件到class文件。

到此,相信大家对"JVM真香系列之如何学习Java文件到.Class文件"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

文件 版本 分析 语法 编译 系统 操作系统 字节 就是 生成 命令 程序 词法 语言 开发 运行 学习 关键 内容 分析器 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 百单网互联网科技有限公司怎么样 科技股互联网 科技互联网政务服务 互联网科技的英文 奔汉互联网科技 赫美联合互联网科技 互联网科技论坛 中正互联网科技招聘 老年人脱离互联网科技的作文 开启互联网科技时代小说 农村开互联网科技讲堂 宁夏科技产业互联网案例 湖北码尼互联网科技有限公司电话 深圳育鹏互联网科技有限公司招聘 四川慕妮娅互联网科技有限公司 为客找房互联网科技公司怎么样 云南省自由互联网科技有限公司 广州互联网高科技取餐柜 互联网领先科技成果宣传视频 株洲百竞科技的互联网营销顾问 上海挚品互联网科技有限公司 科技股互联网 金融科技创新监管互联网金融 多迪互联网科技有限公司 深圳卡尔迅互联网科技有限公司怎么样 江苏南京365互联网科技 上海京穆互联网科技有限公司 易企秀互联网科技是做什么的 科技互联网经济论坛 互联网科技创新创业项目
0