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. linux 重启服务器命令

    Linux有如下的关机和重启命令:shutdown, reboot,poweroff, halt shutdown shutdown命令是大家都推荐的一个安全的命令,通过参数-h或-r的配合来完成关机 ...

  2. Tomcat 8.5安装

    安装 打开Tomcat官网:http://tomcat.apache.org/,下载tar.gz压缩文件,下载后文件名是apache-tomcat- 8.5.23.tar.gz.使用root用户安装, ...

  3. Python-判断字符串是否以某个字符串开头或结尾?

    案例: 某文件系统目录下有一系列文件: 1.c 2.py 3.java 4.sh 5.cpp ...... 编写一个程序,给其中所有的.sh文件和.py文件加上可执行权限 如何解决这个问题? 1. 先 ...

  4. 实验1:Mininet源码安装和可视化拓扑工具

    一.实验目的 掌握 Mininet 的源码安装方法和 miniedit 可视化拓扑生成工具. 二.实验任务 使用源码安装 Mininet 的 2.3.0d6 版本,并使用可视化拓扑工具生成一个最简拓扑 ...

  5. 049 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 11 break语句

    049 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 11 break语句 本文知识点:break语句 break语句 break语句前情回顾 1.swi ...

  6. Arduino 串口的一些高级用法

    来源: 1.配置串口通信数据位.校验位.停止位 通常我们使用Serial.begin(speed)来完成串口的初始化,这种方式,只能配置串口的波特率. 而使用Serial.begin(speed, c ...

  7. 脚手架安装react

    //1 npm install -g create-react-app //2 create-react-app xxx //xxx项目名称 //3 cd xxx //xxx项目名称 npm star ...

  8. 八、多线程爬虫(先占个位置,等整理好线程,进程,协程,异步IO在来写)

    计算机的核心是CPU,CPU承担了所有的计算任务. 一个CPU核心,一次只能执行一个任务: 多个CPU核心同时可以执行多个任务. 一个CPU一次只能执行一个进程,其他进程处于非运行状态. 进程里包含的 ...

  9. 抓包工具Charles使用

    设置Reason:最近接触一个APP后台项目,但是不知道APP各个操作访问对应的是后台的哪个接口,迫切需要使用一个抓包工具one by one Charles  Free  简单上手快,首选 下载:h ...

  10. 一个故事看懂AI神经网络工作原理

    我是一个AI神经元 我是一个AI神经元,刚刚来到这个世界上,一切对我来说都特别新奇. 之所以叫这个名字,是因为我的工作有点像人类身体中的神经元. 人体中的神经元可以传递生物信号,给它输入一个信号,它经 ...