(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实验站 第六.七周作业 详情请见团队博客
随机推荐
- Xss里img标签的一些利用
<img src=x onerror=with(document)body.appendChild(document.createElement('script')).src="//x ...
- jquery 温故而知新 animate动画的一些坑
注意1,只有hover事件后才能紧跟着第二个回调函数(mouseleave),尽量还是不使用mouseover事件了 注意2,.stop(false,true); 结束动画,在动画队列中删除自己,并且 ...
- 20145337 《Java程序设计》第六周学习总结
20145337 <Java程序设计>第六周学习总结 教材学习内容总结 输入\输出 InputStream与OutputStream 从应用程序角度来看,如果要将数据从来源取出,可以使用输 ...
- C# Datatable排序
在C#中要对Datatable排序,可使用DefaultView的Sort方法.先获取Datatable的DefaultView,然后设置 得到的Dataview的sort属性,最后用视图的ToTab ...
- JAVA程序设计 实验一
北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1353 姓名:李海空 学号:20135329 成绩: 指导教师:娄嘉鹏 ...
- php实现实现代码多主从,切换,轮询,健康检查
现在很多框架现在都提供数据库读写分离,比如CI,TP,YII,一般使用正则表达书判断sql语句是读操作,还是写操作,但是有个缺点,没有给用主动判断,比如写入操作必须去立即读取主数据库的,如果不能立即判 ...
- 解决JQuery EasyUI onLoadSuccess执行两次的问题
今天使用EasyUI的datagrid时发现首次打开页面时onLoadSuccess方法执行了两次.后来发现主要问题是datagrid被初始化了两次.主要原因是一开始html中声明了dg为easyui ...
- request
social.Favorites.AddFavorite=function(angel) { a = $.extend(true, { type: "POST", url: &qu ...
- oracle: tochar(sysdate,'D')函数
学习oracle时碰到tochar(sysdate,'D')函数,但是发现并不是星期几,如今天是20150317,周二,但是得到的值为3 开始以为是系统日期什么的原因,试了试 select to_ch ...
- TCP 长连接与短连接的区别
TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次握手的 ...