标签:类型转换 开始 不可 address 完成后 init 作用域 情况 over
一.程序存储格式
二.Class 文件结构
Class 文件是以 8 个字节为单位的二进制流,紧凑排列,中间没有空隙;如果想查看一个 Class 文件除了通过 winHex 编译器看到字节码,也可以通过 javap -verbose xxx.Class 输出字节码内容,这样看起来比较直观。
1、基本类型
无符号数:
表:
2、魔数与版本
3、常量池
版本号之后紧跟的就是常量池入口,可以理解为Class文件之中的资源仓库;
4、访问标志(access_flags)
5、类索引、父类索引和接口类集合
6、字段表集合(field_info)
7、方法表集合
和字段表集合差不多,方法表集合用来描述Class文件中的方法,但是访问标志和属性表集合和字段表集合有所区别;
8、属性表集合(attribute_info)
上述那些表需要携带自己的某些属性,来描述自己的特殊环境信息,比如InnderClasses、LineNumberTable、Code 之类的;
三.字节码指令
1、字节码组成
Java虚拟机采用面向操作数栈而不是寄存器的架构,字节码指令集是一种指令集架构。放弃了操作数对齐,省略了填充的符号和间隔。
2、加载和存储指令
将数据在帧栈中将局部变量表和操作数栈之间来回传输。
3、运算指令
4、类型转换指令
5、同步指令
三.代码举例
1、Java文件:
1 package com.xxx.ccc; 2 public final class InitConfig { 3 public static final InitConfig BFCACCOUNT = new InitConfig(0, "aaa", "AAA"); 4 private int mIndex; 5 private String mData; 6 private String mDescribe; 7 private InitConfig(int indexFlag, String data, String describe) { 8 this.mIndex = indexFlag; 9 this.mData = data; 10 this.mDescribe = describe; 11 } 12 public String getmData() { 13 return this.mData; 14 }
2、Class 文件:
1 Last modified 2017-7-4; size 1050 bytes 2 MD5 checksum 2beb0c10f91b793c3570edcf2d1eff78 3 Compiled from "InitConfig.java" 4 public final class com.xxx.xxx.InitConfig 5 minor version: 0 //次版本号 6 major version: 51 //主版本号 7 flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER //访问标志 8 Constant pool: //常量池 9 #1 = Methodref #14.#41 // java/lang/Object."<init>":()V 10 #2 = Fieldref #5.#42 // com/xxx/xxx/InitConfig.mIndex:I 11 #6 = Class #46 // com/xxx/xxx/common/constant/ConstData 12 #7 = String #47 // aaa 13 #23 = Utf8 <init> 14 #24 = Utf8 (ILjava/lang/String;Ljava/lang/String;)V 15 #25 = Utf8 Code 16 #26 = Utf8 LineNumberTable //Java的源码行号和字节码行号 17 #27 = Utf8 LocalVariableTable //局部变量表中的变量与Java源码中定义的变量之间的关系 18 #28 = Utf8 this 19 #32 = Utf8 getmData 20 #33 = Utf8 ()Ljava/lang/String; 21 #37 = Utf8 <clinit> 22 #38 = Utf8 ()V 23 #40 = Utf8 InitConfig.java 24 #41 = NameAndType #23:#38 // "<init>":()V 25 #45 = Utf8 com/xxx/xxx/InitConfig 26 #46 = Utf8 com/xxx/xxx/common/constant/ConstData 27 #53 = NameAndType #17:#16 // SEAACCOUNT:Lcom/xxx/ccc/InitConfig; 28 #54 = Utf8 java/lang/Object 29 public static final com.xxx.xxx BFCACCOUNT; 30 descriptor: Lcom/xxx/xxx/InitConfig; 31 flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL 32 public java.lang.String getmData(); 33 descriptor: ()Ljava/lang/String; 34 flags: ACC_PUBLIC 35 Code: 36 stack=1, locals=1, args_size=1 37 0: aload_0 38 1: getfield #3 // Field mData:Ljava/lang/String; 39 4: areturn 40 LineNumberTable: //Java的源码行号和字节码行号 41 line 36: 0 42 LocalVariableTable: //局部变量表中的变量与Java源码中定义的变量之间的关系 43 Start Length Slot Name Signature 44 0 5 0 this Lcom/xxx/xxx/InitConfig; //方法里面默认增加了个this
四.小结
为什么说一些”非Java"语言也是可以在 JVM 上跑,这是因为 JVM 只认识 Class 文件,所以如果某某语言最终编译出的文件是 Class 文件,那么对于 JVM 来说没有什么区别,但是得按照 Class 文件的结构来,不然也无法正常执行。Class 定义了许多特定的基本类型和表结构,通过魔数让 JVM 认识该文件,版本号保证可以在要求的 JDK 版本上运行,在常量池中定义好常量,访问标志位确定访问权限。索引集合方便与外界的 class 保持联系,字段表保存我们定义好的变量,方法表存储方法的信息,属性表存储了上述各种表的一些属性。其中记住 slot为局部变量分配内存的最小单位,当程序超出作用域的时候,slot 可以被其他替换使用。到这里,仅仅是代码最静态的存储的格式,程序要运行起来。还需要操作指令,也是由字节码存储,包括操作码和操作数。有加载存储、运算、类型转换、同步指令。
标签:类型转换 开始 不可 address 完成后 init 作用域 情况 over
原文地址:https://www.cnblogs.com/ganchuanpu/p/9429248.html