JVM执行子系统探究——类文件结构初窥

    类文件(.class)是搞java的都非常熟悉的文件,一般我们在编写java之后文件之后,首先通过javac工具生成.class类字节码文件,而后在执行程序的时候由虚拟机加载执行。那么为什么要生成.class呢?直接执行.java文件不行吗?下边我们先来大概了解一下java编译执行流程。

一、class文件存在的意义

1、解释执行和编译执行

    由于要想解释为什么要生成.class,就需要搞清楚解释执行和编译执行的区别,所以首先我们来普及一个知识点:

编译程序、解释程序、汇编程序是3种语言处理程序。
其区别主要为:
汇编程序(为低级服务)是将汇编语言书写的源程序翻译成由机器指令和其他信息组成的目标程序。解释程序(为高级服务)直接执行源程序或源程序的内部形式,一般是读一句源程序,翻译一句,执行一句,不产生目标代码,如BASIC解释程序。编译程序(为高级服务)是将高级语言书写的源程序翻译成与之等价的低级语言的目标程序。编译程序与解释程序最大的区别之一在于前者生成目标代码,而后者不生成。

    汇编程序就不说了,对应后两者我们一般会把语言的执行分为解释执行和编译执行。而我们知道,低级语言是平台相关的,不同操作系统下是不能够通用的,因此编译执行是不能跨平台的(准确的说是其编译后的目标程序),而解释执行却可以用相同的源代码(或中间代码)通过不同解释器在不同的平台上运行。为了更好的理解这一过程,我们分别看一下C++和java的编译、执行过程:
    C++:

   Java:

    从图中可以看出,在初次编译完成后C++生成了.obj,而java生成了class,理论上其实这两类文件都是跨平台的(前提是obj代码不涉及不同平台特性,比如在调了win32接口)。C++不跨平台关键的点就在于链接的时候会链接对应平台的dll库,因此生成的可执行文件当然不能在其他平台运行。而java所谓的打包只是把class文件打包为jar/war,真正执行是由虚拟机加载后处理的,而虚拟机本身则在不同平台下有不同的实现。JIT可以把部分class文件或解释后的指令(如循环等)生成本机机器码,进行编译执行以提高效率。

2、使用class的好处

    将java文件编译成class文件的最主要的原因就是实现跨平台,这一点在前边已经很明显了。第二个原因就是通过class文件,能使虚拟机可以运行其他语言。虚拟机本身和java文件没有关联,它只认识固定格式的class文件,这样一来只要通过编译器把其他语言的源文件编译成这样格式的class,就能在虚拟机上运行,scala、groovy、jython、jruby等都是这样实现的。

二、class文件结构

    下边进入正题,class文件是一组以8位字节为基础单位的二进制流,各数据间没有分隔符,严格按照《java虚拟机规范》所规定的位置来表示代表的定义。
    class文件有两种数据类型:无符号数和表,无符号数属于基本类型,有u1,u2,u4,u8四种,u表示单元,后边的数表示占的字节,u1就表示占1个字节的数(并不是数字,代表的意思要根据所处位置来定,可能是地址值、字符串utf8编码等);而表则是由无符号数或其他表组成的复杂类型,其实相当于结构体,习惯性以'_info'结尾。下图是class文件格式:

    从上边结构可以看出,整个文件的大小都是可知的,当出现可变项时(如cp_info),那么它的前一项一定是这个可变项的数量,这在之后要介绍的加载机制中很重要。
    好了,这次先对class文件有个了解,下一次将详细介绍各部分内容。


 

posted @ 2014-04-27 02:51  oO脾气不坏Oo  阅读(884)  评论(0编辑  收藏  举报