Java 进阶:实例详解 Java 虚拟机字节码指令

众所周知,Java 语言编译生成的 class 文件可以运行在任何支持 Java 虚拟机的硬件平台和操作系统上。那么,你是否思考过:class 文件包含哪些内容?是如何在虚拟机中执行的?要弄清楚这些问题,须了解 class 文件结构和 Java 虚拟机字节码指令。Java 虚拟机字节码指令非常重要,学习它对深入理解虚拟机、栈、锁、异常、同步等的原理十分有益,是Java 进阶之路必读内容之一。

本系列一共有两篇文章,这是第一篇,主要内容如下:

图文解读 class 文件结构;

  • Java 字节码介绍;
  • 详解 Java 虚拟机栈结构;
  • 实例解读 Java 虚拟机中变量、常量访问原理和指令体系;
  • 实例解读 Java 虚拟机中对象、数组(数值数组、对象数组、多维数组)创建指令;
  • 实例解读 Java 虚拟机中方法、字段 (又称域-field) 访问的原理及指令体系。

引言

计算机本身只能识别 0 和 1 构成的机器码,因此,任何编程语言最终都需要编译成机器码才能被计算机执行。以 C/C++ 为例,用它们编写的程序首先被编译,然后被连接成单独的、支持特定硬件平台和操作系统的二进制文件。通常情况下,一个平台上的二进制可执行文件不能在其它平台上工作。

Java 在诞生之初便提出了著名的 slogan:“Write Once, Run Anywhere”,为了实现这一目标,Java 虚拟机应运而生。目前,Java 虚拟机有很多版本,但它们都具有一个共同的特征——可以载入并执行同一种与平台无关的字节码(ByteCode)。 因为 Java 虚拟机的出现,Java 源代码不必根据不同平台编译成 0 和 1,而是间接翻译成字节码,储存字节码的文件再交由运行于不同平台上的 Java 虚拟机去读取执行,从而实现一次编写,到处运行的目的。

Java 编译生成的字节码文件为 ".class " 文件,它是一种二进制文件,其中包含了 Java 虚拟机指令集和符号表以及若干其它辅助信息。作为一个通用的、机器无关的执行平台,任何其它语言的实现者都可以将 Java 虚拟机作为语言的产品交付媒介。例如,使用 Java 编译器可以把 Java 代码编译成存储字节码的 class 文件,使用 Groovy、 Scala、 Koltin 等其它语言的编译器一样可以把程序代码编译成 class 文件,虚拟机并不关心 class 的来源是何种语言。

Class 文件结构

class 文件是一组以 8 位字节位基础单位的二进制流,采用一种类似 C 语言结构体的伪结构来存储数据,这种伪结构只有两种数据类型:无符号数和表。无符号数属于基本的数据类型,以 u1、u2、u4、u8 分别代表1个字节、2个字节、4个字节、8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或 utf-8 编码构成的字符串值。表是由多个无符号数或其它表作为数据项构成的复合数据类型,所有表都习惯性地以 _info 结尾。 每一个 class 文件对应于一个如下所示的 ClassFile 结构体:

ClassFile {
u4 magic; //魔数
u2 minor_version; //副版本号
u2 major_version; //主版本号
u2 constant_pool_count; //常量池计数器,
cp_info constant_pool[constant_pool_count-1]; //常量池列表
u2 access_flags; //访问标志
u2 this_class; //类索引,表示这个Class文件所定义的类或接口
u2 super_class; //父类索引
u2 interfaces_count; //接口计数器
u2 interfaces[interfaces_count]; //接口表,接口顺序和源代码顺序一致
u2 fields_count; //字段计数器
field_info fields[fields_count]; //字段表
u2 methods_count; //方法计数器
method_info methods[methods_count]; //方法表
u2 attributes_count; //属性计数器
attribute_info attributes[attributes_count]; //属性表
}

更直观地,通过图片来展示 class 文件的结构,如下所示:

Java 进阶:实例详解 Java 虚拟机字节码指令_第1张图片

Class 文件结构实例

从上面的介绍 class 文件的结构比较复杂,事实上,我们可以将 class 文件分为以下部分。

class文件: 文件描述、常量池、类概述、字段表、方法表、扩展信息表。为了便于读者理解,在此,我们先来看一个实例,Java 源码如下:

public class Test {
private String attribute_1;
private Integer attribute_2;
public void testMethod_1() {
} public String testMethod_2(String param) {
return param;
}}

通过命令“javac Test.java”编译后,可以得到 Test.class 文件,这就是所谓的字节码文件,Test.class 内容如下所示:

Java 进阶:实例详解 Java 虚拟机字节码指令_第2张图片

最后

希望这篇文章对大家有帮助!

我这边也整理了一份 架构师全套视频教程 和关于java的系统化资料,包括java核心知识点、面试专题和20年最新的互联网真题、电子书等都有。

有需要的朋友可以点一点下方链接免费领取!

链接:1103806531暗号:CSDN

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

你可能感兴趣的:(面试,学习路线阿里巴巴,android,前端,后端)