(6) 深入理解Java Class文件格式(五)
前情回顾
本专栏的前几篇博文, 对class文件中的常量池进行了详细的解释。 前文讲解了常量池中的7种数据项, 它们分别是:
- CONSTANT_Utf8_info
- CONSTANT_NameAndType_info
- CONSTANT_Integer_info
- CONSTANT_Float_info
- CONSTANT_Long_info
- CONSTANT_Double_info
- CONSTANT_String_info
常量池中各数据项类型详解(续)
(8) CONSTANT_Class_info
(9) CONSTANT_Fieldref_info
- package com.jg.zhang;
- public class TestInt {
- int a = 10;
- void print(){
- System.out.println(a);
- }
- }
在print方法中, 引用了本类中的字段a。 代码很简单, 我们一眼就可以看到print方法中是如何引用本类中定义的字段a的。 那么在class文件中, 对字段a的引用是如何描述的呢? 下面我们将这段代码使用javap反编译, 给出简化后的反编译结果:
- Constant pool:
- #1 = Class #2 // com/jg/zhang/TestInt
- #2 = Utf8 com/jg/zhang/TestInt
- ......
- #5 = Utf8 a
- #6 = Utf8 I
- ......
- #12 = Fieldref #1.#13 // com/jg/zhang/TestInt.a:I
- #13 = NameAndType #5:#6 // a:I
- ......
- {
- void print();
- flags:
- Code:
- stack=2, locals=1, args_size=1
- 0: getstatic #19 // Field java/lang/System.out:Ljava/io/PrintStream;
- 3: aload_0
- 4: getfield #12 // Field a:I
- 7: invokevirtual #25 // Method java/io/PrintStream.println:(I)V
- 10: return
- }
(10) CONSTANT_Methodref_info
下面结合实际代码来说明, 代码如下:
- package com.jg.zhang;
- public class Programer {
- Computer computer;
- public Programer(Computer computer){
- this.computer = computer;
- }
- public void doWork(){
- computer.calculate();
- }
- }
- package com.jg.zhang;
- public class Computer {
- public void calculate() {
- System.out.println("working...");
- }
- }
- Constant pool:
- .........
- #12 = Utf8 ()V
- #20 = Methodref #21.#23 // com/jg/zhang/Computer.calculate:()V
- #21 = Class #22 // com/jg/zhang/Computer
- #22 = Utf8 com/jg/zhang/Computer
- #23 = NameAndType #24:#12 // calculate:()V
- #24 = Utf8 calculate
- {
- com.jg.zhang.Computer computer;
- flags:
- .........
- public void doWork();
- flags: ACC_PUBLIC
- Code:
- stack=1, locals=1, args_size=1
- 0: aload_0
- 1: getfield #13 // Field computer:Lcom/jg/zhang/Computer;
- 4: invokevirtual #20 // Method com/jg/zhang/Computer.calculate:()V
- 7: return
- }
可以看到, doWork方法的位置为4的字节码指令invokevirtual引用了索引为20的常量池数据项, 常量池中索引为20的数据项是一个CONSTANT_Methodref_info, 这个CONSTANT_Methodref_info又引用了索引为21和23的两个数据项, 索引为21的数据项是一个CONSTANT_Class_info, 这个CONSTANT_Class_info数据项又引用了索引为22的数据项, 索引为22的数据项是一个CONSTANT_Utf8_info , 他存储了被引用的Computer类中的calculate方法所在的类的全限定名com/jg/zhang/Computer 。 而CONSTANT_Methodref_info所引用的索引为23的数据项是一个CONSTANT_NameAndType_info, 它又引用了两个数据项, 分别为第24项和第12项, 这是两个CONSTANT_Utf8_info , 分别存储了被引用的方法calculate的方法名calculate, 和该方法的描述符()V 。
(11) CONSTANT_InterfaceMethodref_info
下面结合实际代码来说明, 代码如下:
- package com.jg.zhang;
- public class Plane {
- IFlyable flyable;
- void flyToSky(){
- flyable.fly();
- }
- }
- package com.jg.zhang;
- public interface IFlyable {
- void fly();
- }
在上面的代码中, 定义可一个类Plane, 在这个类中有一个IFlyable接口类型的字段flyable, 然后在Plane的flyToSky方法中调用了IFlyable中的fly方法。 这就是源代码中对一个接口中的方法的引用方式, 下面我们反编译Plane, 看看在class文件层面, 对一个接口中的方法的引用是如何描述的。
下面给出反编译结果, 为了简洁期间, 省略了一些不相关的内容:
- Constant pool:
- .........
- #8 = Utf8 ()V
- #19 = InterfaceMethodref #20.#22 // com/jg/zhang/IFlyable.fly:()V
- #20 = Class #21 // com/jg/zhang/IFlyable
- #21 = Utf8 com/jg/zhang/IFlyable
- #22 = NameAndType #23:#8 // fly:()V
- #23 = Utf8 fly
- {
- .........
- com.jg.zhang.IFlyable flyable;
- flags:
- .........
- void flyToSky();
- flags:
- Code:
- stack=1, locals=1, args_size=1
- 0: aload_0
- 1: getfield #17 // Field flyable:Lcom/jg/zhang/IFlyable;
- 4: invokeinterface #19, 1 // InterfaceMethod com/jg/zhang/IFlyable.fly:()V
- 9: return
- }
可以看到, flyToSky方法的位置为4的字节码指令invokeinterface引用了索引为19的常量池数据项, 常量池中索引为19的数据项是一个CONSTANT_InterfaceMethodref_info, 这个CONSTANT_InterfaceMethodref_info又引用了索引为20和22的两个数据项, 索引为20的数据项是一个CONSTANT_Class_info, 这个CONSTANT_Class_info数据项又引用了索引为21的数据项, 索引为21的数据项是一个CONSTANT_Utf8_info , 他存储了被引用的方法fly所在的接口的全限定名com/jg/zhang/IFlyable 。 而CONSTANT_InterfaceMethodref_info所引用的索引为22的数据项是一个CONSTANT_NameAndType_info, 它又引用了两个数据项, 分别为第23项和第8项, 这是两个CONSTANT_Utf8_info , 分别存储了被引用的方法fly的方法名fly, 和该方法的描述符()V 。
总结
(6) 深入理解Java Class文件格式(五)的更多相关文章
- (8) 深入理解Java Class文件格式(七)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22091529 本专栏列前面的一系列博客, 对Class文件中的一部分数据项进行了介绍. 本 ...
- (4) 深入理解Java Class文件格式(三)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21557357 首先, 让我们回顾一下关于class文件格式的之前两篇博客的主要内容. 在 ...
- (5) 深入理解Java Class文件格式(四)
转载:http://blog.csdn.net/zhangjg_blog/article/details/21658415 前情回顾 在上一篇博客深入理解Java Class文件格式(三) 中, ...
- (3) 深入理解Java Class文件格式(二)
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/21487287 在上一篇文章 深入理解Java Class文件格式(一) 中, 介绍了c ...
- (2) 深入理解Java Class文件格式(一)
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/21486985 Class文件在Java体系结构中的位置和作用 在上一篇博客中, 大致讲 ...
- 【由浅入深理解java集合】(五)——集合 Map
前面已经介绍完了Collection接口下的集合实现类,今天我们来介绍Map接口下的两个重要的集合实现类HashMap,TreeMap.关于Map的一些通用介绍,可以参考第一篇文章.由于Map与Lis ...
- 深入理解java虚拟机第五部分高效并发
volatile是java虚拟机提供最轻量级的同步机制. volatile两个特性:1,保证同步的变量对所有线程是可见的.虽然对所有线程是即时可见的,但是却不保证原子性,也就是不保证线程安全,比如对于 ...
- 快速理解Java中的五种单例模式
解法一:只适合单线程环境(不好) package test; /** * @author xiaoping * */ public class Singleton { private static S ...
- 重读《深入理解Java虚拟机》五、虚拟机如何执行字节码?程序方法如何被执行?虚拟机执行引擎的工作机制
Class文件二进制字符流通过类加载器和虚拟机加载到内存(方法区)完成在内存上的布局和初始化后,虚拟机字节码执行引擎就可以执行相关代码实现程序所定义的功能.虚拟机执行引擎执行的对象是方法(均特指非本地 ...
随机推荐
- 【HDU4630 No Pain No Game】 dp思想+线段树的离线操作
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4630 题意:给你n个数据范围在[1,n]中的数,m个操作,每个操作一个询问[L,R],让你求区间[L, ...
- springmvc4+hibernate4+spring4注解一对多级联保存
package com.h3c.zgc.user.entity; import java.util.HashSet; import java.util.Set; import javax.persis ...
- imac上php环境php+apache+mysql
---恢复内容开始--- Mac OS X系统已预装集成了Apache+php,但是在新的系统中苹果取消了图形界面,所以只能从命令行开启了. 启用apache: 打开终端 在终端中可以查看集成的php ...
- c#前3章总结
01.net和c#的区别 大概在2000年,微软推出了一种革命性的产品--.NET(战略) 目标:任何人,在任何地方,使用任何终端设备,都可以访问微软提供的服务. .net Framework:要想让 ...
- java.io包中的字节流—— FilterInputStream和FilterOutputStream
接着上篇文章,本篇继续说java.io包中的字节流.按照前篇文章所说,java.io包中的字节流中的类关系有用到GoF<设计模式>中的装饰者模式,而这正体现在FilterInputStre ...
- Android课程---qq登陆页面(练习)
AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xm ...
- Git subtree和Git submodule
git submodule允许其他的仓库指定以一个commit嵌入仓库的子目录. git subtree替代git submodule命令,合并子仓库到项目中的子目录.不用像submodule那样每次 ...
- GDC2016【For Honor-荣耀战魂】的次世代动画技术
生成自然丰富,反应灵敏的动作的“Motion Matching”是什么? Ubisoft在2016年内预定发售的[荣誉战魂],是基于MOBA类集团战斗,并加入了高度紧张的剑斗动作的多人 ...
- 字节流与字符流的区别&&用字节流好还是用字符流好?
字节流: (A)FileOutputStream(File name) 创建一个文件输出流,向指定的 File 对象输出数据. (B)FileOutputStream(FileDescriptor) ...
- gets(),fgets()的作用机制探究
gets(),fgets() scanf("%d",&a)若接受形如 2 这样的输入后,缓冲区内会留一个\n,此后若调用gets等函数时会读出这个换行出现错误,需注意 fg ...