JVM真香系列:Java文件到.Class文件

2025-05-29 0 29

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安装版本等。

JVM真香系列:Java文件到.Class文件

认识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版本情况

JVM真香系列:Java文件到.Class文件

这个混个眼熟就行,随时关注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

JVM真香系列:Java文件到.Class文件

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

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

`javac`命令

编写一个HelloWorld.java文件

JVM真香系列:Java文件到.Class文件

内容就是一个Java入门

publicclassHelloWorld{

publicstaticvoidmain(String[]args){

System.out.println("Helloworld");

}

}

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

javacHelloWorld.java

就编译出HelloWorld.class

JVM真香系列:Java文件到.Class文件

JVM真香系列:Java文件到.Class文件

编译过程

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

javac背后大致做了这些操作

JVM真香系列:Java文件到.Class文件

这个流程

JVM真香系列:Java文件到.Class文件

1、词法分析

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

2、语法分析

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

3、语义分析

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

4、生成字节码

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

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

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

JVM真香系列:Java文件到.Class文件

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。

packagecom.tian.demo.test;

publicclassUser{

privateintage=22;

privateStringname="tian";

publicintaddAge(){

returnage=age+1;

}

publicstaticvoidmain(String[]args){

}

}

JVM真香系列:Java文件到.Class文件

使用javap命令

javap-vUser.class>log.txt

打开log.txt

Classfile/D:/workspace/new/demo/src/main/java/com/tian/demo/test/User.class

Lastmodified2020-11-5;size441bytes

MD5checksum2fa72d3f53bd9f138e0bfae82aba67e3

Compiledfrom"User.java"

publicclasscom.tian.demo.test.User

minorversion:0

majorversion:52

flags:ACC_PUBLIC,ACC_SUPER

Constantpool:

#1=Methodref#6.#21//java/lang/Object."<init>":()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=Utf8age

#8=Utf8I

#9=Utf8name

#10=Utf8Ljava/lang/String;

#11=Utf8<init>

#12=Utf8()V

#13=Utf8Code

#14=Utf8LineNumberTable

#15=Utf8addAge

#16=Utf8()I

#17=Utf8main

#18=Utf8([Ljava/lang/String;)V

#19=Utf8SourceFile

#20=Utf8User.java

#21=NameAndType#11:#12//"<init>":()V

#22=NameAndType#7:#8//age:I

#23=Utf8tian

#24=NameAndType#9:#10//name:Ljava/lang/String;

#25=Utf8com/tian/demo/test/User

#26=Utf8java/lang/Object

{

publiccom.tian.demo.test.User();

descriptor:()V

flags:ACC_PUBLIC

Code:

stack=2,locals=1,args_size=1

0:aload_0

1:invokespecial#1//Methodjava/lang/Object."<init>":()V

4:aload_0

5:bipush22

7:putfield#2//Fieldage:I

10:aload_0

11:ldc#3//Stringtian

13:putfield#4//Fieldname:Ljava/lang/String;

16:return

LineNumberTable:

line3:0

line4:4

line5:10

publicintaddAge();

descriptor:()I

flags:ACC_PUBLIC

Code:

stack=3,locals=1,args_size=1

0:aload_0

1:aload_0

2:getfield#2//Fieldage:I

5:iconst_1

6:iadd

7:dup_x1

8:putfield#2//Fieldage:I

11:ireturn

LineNumberTable:

line8:0

publicstaticvoidmain(java.lang.String[]);

descriptor:([Ljava/lang/String;)V

flags:ACC_PUBLIC,ACC_STATIC

Code:

stack=0,locals=1,args_size=1

0:return

LineNumberTable:

line13:0

}

SourceFile:"User.java"

  • 魔数与class文件版本
  • 常量池
  • 访问标志
  • 类索引、父类索引、接口索引
  • 字段表集合
  • 方法表集合
  • 属性表集合

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

JVM真香系列:Java文件到.Class文件

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

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 JVM真香系列:Java文件到.Class文件 https://www.kuaiidc.com/115999.html

相关文章

发表评论
暂无评论