Java 实现一次编译到处运行的基础,来源于 Java 虚拟机屏蔽了操作系统的底层细节。使用 class 文件存储编译后的源程序,使得 Java 程序的编译与操作系统解耦。正是因为 Java class 文件的设计与 Java 语言解耦,分别发布了 Java语言规范和 Java 虚拟机规范,使得其他语言如Scala、Groovy、JRuby、JPython 等基于Java 虚拟机的语言按照 class 文件格式要求生成的class 文件也能在虚拟机上运行。

class 文件格式

class 文件采用如下的结构存储二进制内容。其中 u2、u4 分别表示占用 2、4 个字节。

{

u4 magic; //魔数,固定为0xCAFEBABE

u2 minor_version; //次版本号

u2 major_version; //主版本号

u2 constant_pool_count; //常量池计数器

cp_info constant_pool[constant_pool_count-1]; //常量池

u2 access_flags; //访问标志,声明权限

u2 this_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 文件内容解读

常量池:

存储 class 文件用到的所有的字符串常量、类名、接口名、字段名以及其他常量。class 文件的其他项目往往会引用常量池中的常量,因此常量池容量计数从1开始,0 用于表示其他项目不引用常量池。在常量池中主要存储了字面量和符号引用两大类常量,字面量主要是字符串、final 类型常量值等,符号引用则包括类和接口的全限定名、字段的名称和描述法以及方法的名称和描述符。在前文《 Java 虚拟机类加载机制》中提到的符号引用转换为直接引用中的符号引用就是常量池中的符号引用。

访问标志:

类或接口的访问权限信息,包括 public、final、super、interface、abstract、annotation、enum 几种属性,以及使用 synthetic 表示非 Java 源码生成的代码。

类索引:

this_class 存储常量池中的一个索引,索引处的常量表示 class 文件定义的类或接口。如果这是一个类,super_class 为 0 或存储常量池中的一个索引,索引处的常量表示父类;如果这是一个接口,super_class 存储常量池中的一个索引,索引处的常量一定是 java.lang.Object。通过 this_class 可以确定当前类的全限定名,通过 super_class 可以确定父类的全限定名。

接口列表:

如果这是一个类,存储该类实现的接口列表,按照 implements 后的接口顺序存储;如果这是一个接口,存储该接口的所有父接口列表,按照 extends 后的接口顺序存储。

字段列表:

存储类或接口声明的变量,包括类变量和实例变量。描述了每个变量的信息,包括作用域、static、final、volatile、transient、类型、名称等。其中字段的名称、类型需要引用常量池中的常量来描述。

方法列表:

存储类或接口声明的方法,包括类方法和实例方法。描述了每个方法的信息,包括访问标志、名称索引、描述符索引、属性表集合等。这里仅仅存储了方法的信息,方法的实现代码编译成字节码后存储在属性表集合中的 “ Code ” 属性里面。

属性列表:虚拟机规范定义了大量的属性,class 文件、字段列表、方法列表都可以使用属性描述专有信息。而属性的名称需要引用常量池的常量来表示。方法体中的代码经编译后就存放在名为 Code 的属性中。

总结

Java 源程序编译后生成 class 文件而不是二进制可执行文件,通过 Java 虚拟机来解析并执行 class 文件中的程序,实现了“一次编译,到处运行”。在 class 文件中,存储了类或接口的基本信息,如版本号、类名、接口列表、字段列表、方法列表等。

原文地址:Java到处运行的基础之 Class 文件

Java到处运行的基础之 Class 文件的更多相关文章

  1. java 程序运行的基础知识【Java bytecode】

    聊聊文字,写一篇关于 java 基础知识的博文. JVM 线程栈 到 函数运行 每一个JVM线程来说启动的时候都会创建一个私有的线程栈.一个jvm线程栈用来存储栈帧,jvm线程栈和C语言中的栈很类似, ...

  2. [Java] Java 技术和 JVM 基础

    Java 由 Sun 公司在 1995 首次发布,既是一门编程语言,也是一个计算平台. Java 运行时版本 Java Runtime Edition 当你下载 Java 完时候,你会得到一个 Jav ...

  3. 【Java_基础】cmd下使用java命令运行class文件提示“错误:找不到或无法加载主类“的问题分析

    1.问题如下 当在命令行使用java命令执行字节码文件时提示“错误:找不到或无法加载主类” 2. 问题分析 这是由于在运行时类的全名应该是包名+类名,例如在包net.xsoftlab.baike下的类 ...

  4. java的运行机制(基础)

    1:高级语言的运行机制: 我们编程都是用的高级语言(写汇编和机器语言的大牛们除外),计算机不能直接理解高级语言,只能理解和运行机器语言,所以必须要把高级语言翻译成机器语言,计算机才能运行高级语言所编写 ...

  5. Java基础之Java编译运行过程

    Java编译运行过程 程序员所编写的是以.java为后缀的文件,此文件操作系统不能正确识别,因此,首先要经过编译,生成所谓的字节码文件(.class),而字节码文件需要JVM来提供运行环境的支持. J ...

  6. 关于JAVA,特点,历史,编译式的语言&解释式的语言,什么是java?JDK?DOS?一次编译到处运行原理。

    1.java语言的特点: 简单的:面向对象的:跨平台(操作系统)的(一次编译,到处运行):高性能的: 2.类名的首字母大写,方法小写: 3.历史: java2(即java),为什么加个2呢?1998年 ...

  7. JVM(二),Java怎样实现一次编译到处运行(平台无关性)

    二.Java怎样实现一次编译到处运行(平台无关性) 1.java平台无关性原理 Java源码首先被编译成字节码,再由不同平台的JVM进行解析,JAVA语言在不同的平台上运行时不需要进行重新编译,Jav ...

  8. 零基础怎么学Java?Java的运行机制是什么?Java入门基础!

    Java语言是当前流行的一种程序设计语言,因其安全性.平台无关性.性能优异等特点,受到广大编程爱好者的喜爱. 想学习Java语言的同学对于Java的运行机制是必须要了解的!! 计算机高级语言的类型主要 ...

  9. 02 基础 卸载JDK 安装JDK Java程序运行机制

    基础 JDK:Java Development Kit(Java开发者工具 包含JRE和JVM) JRE:Java Runtime Environment(java运行时环境,包含JVM) JVM:J ...

随机推荐

  1. org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null

    通过这个简单的案例,手把手教给你分析异常信息(适合初学者看) org.springframework.dao.InvalidDataAccessApiUsageException: The given ...

  2. EM 算法 Expectation Maximization

  3. 剑指offer-链表&数组

    1.圆圈中最后剩下的数 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈. ...

  4. Java知识系统回顾整理01基础04操作符04位操作符

    一.位操作符 位操作符在实际工作中用的并不常见,但是我比较纠结这些位操作.所以实际练习位操作符的每一个操作符的操作实例来理解其具体含义. 建议: 如果确实感兴趣,就看看,个人建议跳过这个章节. 真正工 ...

  5. Java知识系统回顾整理01基础03变量01变量定义

    定义: 变量:用来命名一个数据的标识符 一.什么是变量? 用具体实例定义变量 变量的定义是: 用来命名一个数据的标识符 1949 这是一个数字,代表某年 如果要命名这个数字,在java里就会写成: i ...

  6. np.random.multivariate_normal方法浅析

    从多元正态分布中抽取随机样本. 多元正态分布,多正态分布或高斯分布是一维正态分布向更高维度的推广.这种分布由其均值和协方差矩阵来确定.这些参数类似于一维正态分布的平均值(平均值或"中心&qu ...

  7. ✅Vue选择图像

    下载 Vue选择图像Vue选择图像 Vue 2.用于从列表中选择图像的组件 演示 https://mazipan.github.io/vue-select-image/ 安装 #纱 纱添加vue-se ...

  8. Java源码详解系列(十一)--Spring的使用和源码

    Spring 是一个一站式的 Java 框架,致力于提高我们项目开发的效率.通过 Spring,我们可以避免编写大量额外代码,更专注于我们的核心逻辑.目前,Spring 已经成为最受欢迎的 Java ...

  9. rxjs入门3之项目中ajax函数封装

    项目中ajax函数封装 ⽹页应⽤主要数据源有两个:⼀个是⽹页中的DOM事件,另⼀个就是通过AJAX获得的服务器资源.我们已经知道fromEvent这个操作符可以根据DOM事件产⽣Observable对 ...

  10. 【故障公告】博客系统升级到 .NET 5.0 引发的故障

    昨天晚上我们将博客系统从 .NET Core 3.1 升级到了 .NET 5.0 ,本来是一次很有信心的升级,但没有想到在今天下午访问高峰时竟然出现了故障,大量请求访问速度变慢或者因为下面的数据库连接 ...