(7) 深入了解Java Class文件格式(六)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21888943
经过前几篇文章, 终于将常量池介绍完了, 之所以花这么大的功夫介绍常量池, 是因为对于理解class文件格式,常量池是必须要了解的, 因为class文件中其他地方,大量引用了常量池中的数据项。 对于还不了解常量池的读者, 如果想要深入了解class文件格式, 或者想继续读这篇博客和本专栏以后的博客, 那么我建议先把我前面的几篇博客读一下,把常量池的结构熟悉一下, 对于理解后面的内容很有帮助。
虽然介绍完了常量池, 但是class文件中位于常量池下面的内容还有很多呢。 接下来, 我们就分析class文件中位于常量池下面的内容, 不用担心, 只要把常量池搞明白了, 这些内容就会很容易理解。
在开始进入正文之前, 在这里再次给出class文件的整体格式。 这个表格曾出现在 深入理解Java Class文件格式(一) 这篇文章中。 之所以把这个表格列在这里, 是想再次给读者一个class文件的总体概览。表格的内容如下:
| 类型 | 名称 | 数量 |
| u4 | magic | 1 |
| u2 | minor_version | 1 |
| u2 | major_version | 1 |
| u2 | constant_pool_count | 1 |
| cp_info | constant_pool | constant_pool_count - 1 |
| u2 | access_flags | 1 |
| u2 | this_class | 1 |
| u2 | super_class | 1 |
| u2 | interfaces_count | 1 |
| u2 | interfaces | interfaces_count |
| u2 | fields_count | 1 |
| field_info | fields | fields_count |
| u2 | methods_count | 1 |
| method_info | methods | methods_count |
| u2 | attribute_count | 1 |
| attribute_info | attributes | attributes_count |
下面我们就开始介绍class文件中的其他内容。
class文件中的访问标志信息
| 标志名 | 标志值 | 标志含义 | 针对的对像 |
| ACC_PUBLIC | 0x0001 | public类型 | 所有类型 |
| ACC_FINAL | 0x0010 | final类型 | 类 |
| ACC_SUPER | 0x0020 | 使用新的invokespecial语义 | 类和接口 |
| ACC_INTERFACE | 0x0200 | 接口类型 | 接口 |
| ACC_ABSTRACT | 0x0400 | 抽象类型 | 类和接口 |
| ACC_SYNTHETIC | 0x1000 | 该类不由用户代码生成 | 所有类型 |
| ACC_ANNOTATION | 0x2000 | 注解类型 | 注解 |
| ACC_ENUM | 0x4000 | 枚举类型 | 枚举 |
其他标志就不做介绍了, 这些标志都很简单。 读者感觉比较陌生的可能是ACC_SUPER这个标志。 读者会想, 类型不能被super关键字修饰啊, 那这个ACC_SUPER是做什么的呢?表中可以看出, 它的含义是:使用新的invokespecial语义 。 invokespecial是一个字节码指令, 用于调用一个方法, 一般情况下, 调用构造方法或者使用super关键字显示调用父类的方法时, 会使用这条字节码指令。 这正是ACC_SUPER这个名字的由来。 在java 1.2之前, invokespecial对方法的调用都是静态绑定的, 而ACC_SUPER这个标志位在java 1.2的时候加入到class文件中, 它为invokespecial这条指令增加了动态绑定的功能。 这里可能有几个概念读者不是很明白, 如静态绑定, 动态绑定等, 这些概念会在以后的博客中详细介绍。
class文件中的this_class
访问标志access_flags 下面的两个字节叫做this_class, 它是对当前类的描述。 它的两个字节的数据是对常量池中的一个CONSTANT_Class_info数据项的一个索引。 CONSTANT_Class_info在上面的文章中已经介绍过了。 CONSTANT_Class_info中有一个字段叫做name_index , 指向一个CONSTANT_Utf8_info , 在这个CONSTANT_Utf8_info 中存放着当前类的全限定名。
- package com.jg.zhang;
- public class Person {
- int age;
- int getAge(){
- return age;
- }
- }
将Person.class反编译后, 可以在常量池中看到如下两项:
- Constant pool:
- #1 = Class #2 // com/jg/zhang/Person
- #2 = Utf8 com/jg/zhang/Person
- .........
- .........
class文件中的super_class
- package com.jg.zhang;
- public class Programer extends Person{
- Computer computer;
- public Programer(Computer computer){
- this.computer = computer;
- }
- public void doWork(){
- computer.calculate();
- }
- }
上面的Programer类继承自Person类。 那么反编译Programer .class , 它的常量池中会存在如下信息:
- Constant pool:
- .........
- .........
- #3 = Class #4 // com/jg/zhang/Person
- #4 = Utf8 com/jg/zhang/Person
这两项就是当前类的父类的信息。 其中索引为3的CONSTANT_Class_info会被class文件中的super_class引用。 下面给出示例图(其中虚线范围内表示常量池的区域):
class文件中的interfaces_count和interfaces
- package com.jg.zhang;
- public class Plane implements IFlyable, Cloneable{
- @Override
- public void fly() {
- }
- }
Plane类实现了一个自定义的IFlyable接口, 还实现了一个JDK中的Cloneable接口, 那么它的常量池中会有如下信息:
- Constant pool:
- .........
- .........
- #5 = Class #6 // com/jg/zhang/IFlyable
- #6 = Utf8 com/jg/zhang/IFlyable
- #7 = Class #8 // java/lang/Cloneable
- #8 = Utf8 java/lang/Cloneable
- .........
- .........
这四项数据就是当前的Plane类所实现的接口的信息。 第五项和第六项描述了Plane所实现的IFlyable接口, 第七项和第八项描述了Plane所实现的接口Cloneable接口。 下面是示意图(其中虚线范围内表示常量池的区域):
总结
(7) 深入了解Java Class文件格式(六)的更多相关文章
- (10) 深入了解Java Class文件格式(九)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22432599 经过前八篇关于class文件的博客, 关于class文件格式的内容也基本上讲 ...
- (8) 深入理解Java Class文件格式(七)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22091529 本专栏列前面的一系列博客, 对Class文件中的一部分数据项进行了介绍. 本 ...
- (9) 深入了解Java Class文件格式(八)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22205831 在本专栏的第一篇文章 深入理解Java虚拟机到底是什么 中, 我们主要讲解了 ...
- (6) 深入理解Java Class文件格式(五)
前情回顾 本专栏的前几篇博文, 对class文件中的常量池进行了详细的解释. 前文讲解了常量池中的7种数据项, 它们分别是: CONSTANT_Utf8_info CONSTANT_NameAndTy ...
- (5) 深入理解Java Class文件格式(四)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21658415 前情回顾 在上一篇博客深入理解Java Class文件格式(三) 中, ...
- (4) 深入理解Java Class文件格式(三)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21557357 首先, 让我们回顾一下关于class文件格式的之前两篇博客的主要内容. 在 ...
- (3) 深入理解Java Class文件格式(二)
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/21487287 在上一篇文章 深入理解Java Class文件格式(一) 中, 介绍了c ...
- 从ConcurrentHashMap的演进看Java多线程核心技术 Java进阶(六)
本文分析了HashMap的实现原理,以及resize可能引起死循环和Fast-fail等线程不安全行为.同时结合源码从数据结构,寻址方式,同步方式,计算size等角度分析了JDK 1.7和JDK 1. ...
- 2017-2018-1 JAVA实验站 第六、七周作业
2017-2018-1 JAVA实验站 第六.七周作业 详情请见团队博客
随机推荐
- websocket总结
一.WebSocket简介 WebSocket protocol是HTML5一种新的协议,WebSocket 是目前唯一真正实现全双工通信的服务器向客户端推送的互联网技术.WebSocket的出现使 ...
- log4j日志输出级别高低
Log4j是Apache的开源项目一个功能强大的日志组件,提供方便的日志记录.日志记录器(Logger)是日志处理的核心组件Log4j建议只使用四个级别,优先级从高到低分别是FATAL, ERROR. ...
- java容器学习
容器是java中重要的一部分,其接口的结构如下 Collection | ------------------ Map | | | Set List HashMap | HashSet 顾名思义,容器 ...
- 解决Android调用https服务API时出错的问题
今天同事告诉我说他的应用调用我开发的API报异常了,原因跟SSL有关系,因为之前调试一直调用的是HTTP服务API,今天调试HTTPS服务API时报错了,并且找到了一篇文章让我看了一眼,文章中提到了W ...
- 安装好php后,配置httpd以便支持php3脚本
Apache是目前应用最广的Web服务器,PHP是一种类似ASP的易学的脚本语言,而且性能和功能都比ASP要强,而MySQL又是一个Linux上应用最多的数据库系统,特别是用于网站建设,这3个软件均是 ...
- Python一般错误
1. IndentationError: unindent does not match any outer indentation level 格式对齐的问题.Python对空格和Tab有严格区别
- Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC
Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC 博客分类: Java/Security Javabase64macmd5sha 加密解密,曾经是我一 ...
- centos安装配置amoeba以及测试
一.amoeba介绍网址:http://docs.hexnova.com/amoeba/ 二.安装java se1.5 三.安装amoeba2.2.01.下载地址:http://sourceforge ...
- C#中判断字符是否大写
在C#中,通常判断一个字符是否为大写字母,有些人可能会第一时间想到用正则表达式,那除了正则表达式,是否还有其他方式呢? 答案是肯定的,先一睹为快,具体代码如下: using System; using ...
- Oracle的日期时间范围查询
Oracle日期时间范围查询 Sql代码 /* 日期时间范围查询 */ ---------- 创建日期时间测试表-------------------------------------------- ...