关闭

【理解HostSpot虚拟机】class文件格式

标签: 虚拟机java
628人阅读 评论(0) 收藏 举报
分类:

转载请注明出处:http://blog.csdn.net/linxdcn/article/details/73472553


1 概述

Java编译后的class文件格式如下定义:

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;
    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];
}
  • magic:魔数,固定为0xCAFEBABE
  • minor_version:次版本号
  • major_version:主版本号
  • constant_pool_count:常量池项个数
  • constant_pool[constant_pool_count-1]:常量池表,长度为constant_pool_count-1
  • access_flags:类或接口的访问标志
  • this_class:当前类
  • super_class:超类
  • interfaces_count:接口数量
  • interfaces[interfaces_count]:接口表
  • fields_count:字段数量
  • fields[fields_count]:字段表
  • methods_count:方法数量
  • methods[methods_count]:方法表
  • attributes_count:属性数量
  • attributes[attributes_count]:属性表

关于class文件中的各项说明,可以参考虚拟机规范或者底下参考文献的两篇文章,已经总结的非常的详细,本文对其中重要的几项作一个总结。


2 常量池

  • 常量池保存了文件中类或接口相关的一切常量:
    • 字面量:文字字符串、final变量值、基础数据类型
    • 符号引用:如类或接口的全限定名、方法或字段的简单名称和描述符

根据虚拟机规范,常量池项目类型有以下分类



JVM规范规定的常量池项目类型

规范规定的总是很抽象的,下面举几个例子就好懂。

2.1 int a = 10

类型 常量池索引 备注
CONSTANT_Integer 1 10 字面量:基础数据类型

2.2 String a = “test”

类型 常量池索引 备注
CONSTANT_String 1 #2 符号引用
CONSTANT_Utf8 2 test 字面量:文字字符串

2.3 Date a = new Date()

类型 常量池索引 备注
CONSTANT_Class 1 #1 符号引用:类全限定名
CONSTANT_Utf8 2 Ljava/util/Date; 字面量:文字字符串

2.4 Field常量

在类中定义了field 字段,并且在类的其他地方(如方法中)使用到它,这是会用到Field常量,如以下代码

Class Test {
    String name;
    public void setName(String a) {
        // 这里会使用Field常量
        name = a;  // 翻译成指令为: getfield    #5
    }
}
类型 常量池索引 备注
CONSTANT_Class 1 #2 符号引用
CONSTANT_Utf8 2 package/path/Test 字面量:文字字符串
CONSTANT_Utf8 3 name 字面量:文字字符串
CONSTANT_Utf8 4 Ljava/lang/String; 字面量:文字字符串
CONSTANT_Fieldref 5 #1.#6 符号引用
CONSTANT_NameAndType 6 #3.#4 符号引用

2.5 Method常量

假如我们只定义了方法,但是这些方法没有在类总的其他地方被用到(如2.3中的代码),则这些方法引用信息并不会放到常量中。下面代码则可以使用到Method常量。

Class Test {
    String name;
    public String getName() {
        return name;
    }
    public do() {
        // 这里会使用Method常量
        setName("test");  // 翻译成指令为: invokevirtual    #5
    }
}
类型 常量池索引 备注
CONSTANT_Class 1 #2 符号引用
CONSTANT_Utf8 2 package/path/Test 字面量:文字字符串
CONSTANT_Utf8 3 getName 字面量:文字字符串
CONSTANT_Utf8 4 ()java/lang/String; 字面量:文字字符串
CONSTANT_Methodref 5 #1.#6 符号引用
CONSTANT_NameAndType 6 #3.#4 符号引用

3 字段表-field_info[]

首先需要说明的是,属性不仅在class文件结构中使用,在field_info和method_info中也使用。

在字段域出现的属性有ConstantValue(final常量)、Deprecated(被禁用的指示符)、Synthetic(编译器产生的指示符)。

4 方法表-method_info[]

方法域出现的属性有Code、Deprecated、Exceptions、Synthetic 。

(1)Code

Code类型的属性表(attribute_info)可以说是class文件中最为重要的部分,因为它包含的是JVM可以运行的机器码指令,JVM能够运行这个类,就是从这个属性中取出机器码的。

Code属性表包含:

  • 机器指令—-code:
  • 异常处理跳转信息—exception_table
  • Java源码行号和机器指令的对应关系—LineNumberTable属性表
  • 局部变量表描述信息—-LocalVariableTable属性表

5 一些思考

(1)常量池的CONSTANT_Fieldref和跟字段域field_info的区别?

CONSTANT_Fieldref,这只是一个字段的符号引用,通常作为字节码指令(opcode)getfield/getstatic/putfield/putstatic的操作数使用。

field_info是类中定义字段本身信息的描述,关于类加载过程中field部分的解析,以及其作为InstanceKlass类中成员属性的layout。

对于getfield/getstatic/putfield/putstatic四种与Field Reference相关的指令,在字段决议——resolve_field时,会有两者的协同使用——根据符号引用去_field中查找真正的字段。符号引用只是一个对应字段的一个字符串,符号引用经第一次解析(解析结果存入ConstantPoolCache),就会变成直接引用——field_offset。

对于CONSTANT_Methodref和方法域method_info也类似。

(2)如何防止class文件被劫持?

主要通过类加载双亲委派模型实现。

jvm首先会检查该类是否已经被加载,若没有被加载,则会委托父加载器进行装载,只有当父加载器无法加载时,才会调用自身的findClass()方法进行加载。这样避免了子加载器加载一些试图冒名顶替可信任类的不可靠类,也不会让子加载器去实现父加载器实现的加载工作。

并且jvm规定只有运行时包(同一个类加载器加载的、属于同一个包的多个类型集合),才能访问同一包内的类(和其子类)的protected成员。

(3)如何防止class文件反编译?

可以参考下这篇博客:http://blog.csdn.net/yuxiaohui78/article/details/8247096


6 参考

http://blog.csdn.net/luanlouis/article/details/39892027
http://www.cnblogs.com/iceAeterNa/p/4874197.html


转载请注明出处:http://blog.csdn.net/linxdcn/article/details/73472553

0
0
查看评论

[Java]深入理解Java Class文件格式(四)

前情回顾 在上一篇博客深入理解Java Class文件格式(三) 中, 介绍了常量池中的两种类型的数据项, 分别是 CONSTANT_Utf8_infoCONSTANT_NameAndType_info 。 CONSTANT_Utf8_info中存储了几乎所有...
  • szwangdf
  • szwangdf
  • 2014-05-12 14:20
  • 1509

深入理解Java Class文件格式(三)

首先, 让我们回顾一下关于class文件格式的之前两篇博客的主要内容。 在 深入理解Java Class文件格式(一) 中, 讲解了class文件在整个java体系结构中的位置和作用, 讲解了class文件中的魔数和版本号相关的信息, 并且对常量池进行了概述。 在 深入理解Java Class文件格...
  • brave2211
  • brave2211
  • 2014-03-20 23:58
  • 9126

深入理解Java Class文件格式(六)

经过前几篇文章, 终于将常量池介绍完了, 之所以花这么大的功夫介绍常量池, 是因为对于理解class文件格式,常量池是必须要了解的, 因为class文件中其他地方,大量引用了常量池中的数据项。  对于还不了解常量池的读者, 如果想要深入了解class文件格式, 或者想继续读这篇博客和本专栏...
  • brave2211
  • brave2211
  • 2014-03-24 01:03
  • 17697

深入理解Java Class文件格式(二)

在上一篇文章 深入理解Java Class文件格式(一) 中, 介绍了class文件在整个java体系结构中的位置和作用, 并对class文件的整体格式做了说明, 介绍了其中的魔数和版本号的相关内容, 并对常量池做了概述。 在本文章, 继续介绍class文件中的其他内容。 class文件中的特殊字...
  • brave2211
  • brave2211
  • 2014-03-19 21:28
  • 9344

Java虚拟机:class文件格式

本博文目的:通过本片博文的阅读,希望大家能够能class文件格式有一个直观的认识,同时对其中的一些实现细节也能有一定的掌握。本文并不会说的太细,太细节化的东西,真的太多,涉及到一大堆属性和验证的过程。我都看烦了,不仅记不住,而且也不是我们所关心的东西。 每一个class文件都对应着唯一一个类或接口的...
  • jcw321
  • jcw321
  • 2017-06-15 15:42
  • 147

[Java]深入理解Java Class文件格式(二)

在上一篇文章 深入理解Java Class文件格式(一) 中, 介绍了class文件在整个java体系结构中的位置和作用, 并对class文件的整体格式做了说明, 介绍了其中的魔数和版本号的相关内容, 并对常量池做了概述。 在本文章, 继续介绍class文件中的其他内容。 ...
  • szwangdf
  • szwangdf
  • 2014-05-12 13:44
  • 1931

深入理解Java Class文件格式(一)

在上一篇博客中, 大致讲解了Java虚拟机的体系结构和执行原理。 本篇博客主要讲解能够被JVM识别, 加载并执行的class文件的格式。 对于理解JVM和深入理解Java语言, 学习并了解class文件的格式都是必须要掌握的功课。 原因很简单, JVM不会理解我们写的Java源文件, 我们必须把J...
  • brave2211
  • brave2211
  • 2014-03-18 23:31
  • 31537

《深入理解java虚拟机》笔记——简析java类文件结构

一直不太搞得明白jvm到底是如何进行类加载的,在看资料的过程中迷迷糊糊,在理解类加载之前,首先看看java的类文件结构到底是怎样的,都包含了哪些内容。  最直接的参考当然是官方文档:The Java® Virtual Machine Specification  我写了一个最简单的java...
  • zhoufenqin
  • zhoufenqin
  • 2016-04-03 15:31
  • 2043

vmware 各个文件类型说明

VMware虚拟机文件夹中各文件作用详解转自:http://blog.sina.com.cn/s/blog_5551d4480101cpzb.html虚拟机的文件管理由VMware Workstation来执行。 一个虚拟机一般以一系列文件的形式储存在宿主机中, 这些文件一般在由workstat...
  • u014132720
  • u014132720
  • 2016-07-14 14:13
  • 532

深入理解Java Class文件格式(七)

本专栏列前面的一系列博客, 对Class文件中的一部分数据项进行了介绍。 本文将会继续介绍class文件中未讲解的信息。 先回顾一下上面一篇文章。 在上一篇博客中, 我们介绍了: this_class    对当前类的描述 super_class    对当前...
  • brave2211
  • brave2211
  • 2014-03-25 22:51
  • 4836
    个人资料
    • 访问:37874次
    • 积分:874
    • 等级:
    • 排名:千里之外
    • 原创:51篇
    • 转载:0篇
    • 译文:0篇
    • 评论:6条
    博客专栏
    最新评论