首页 > 代码库 > class文件格式说明
class文件格式说明
java代码编译成class文件之后,class文件里面的语法是什么样的,他的数据类型是什么以及如何存放的??
class也是一种语言写的,只不过和我们的java语法不同而已。
class文件就是把java文件转换成他自己的语法格式(类比把java的排序算法用C++写一样,仅仅是语法的不同而已)
=====================================================================================================
class文件时给虚拟机看的,所以比较紧凑,尽量减少存储空间
=====================================================================================================
数据类型:基本单位为一个字节为单位:
基本类型:u1,u2,u4,u8
表类型:u1,u2,u3,u4类型的组合体(类似于结构体或者对象体)
对呀,class数据类型就仅仅这两种,不像java里面的Int,Long,Object这么多的数据类型(给开发人员看的,所以比较丰富,不想给计算机看的就0.1,人看的太复制,浪费时 间)。
====================================================================================================
1.魔数(文件格式的表示,就是一个标示作用)
2.版本(什么版本的java)
3.常量池:(仅仅是对一些表述信息的应用)------仅仅存储应用(看来class文件也就应用)
class类名,字段类型,方法,构造方法,静态方法 这些信息的属于类的数据结构信息,是一个模板(操作指令流程组合)信息,所以在Class存储常量池里面引用
init-----自动添加的构造方法
clinit---自动添加的静态快
例子:
package com.jg.zhang;public class Programer extends Person { static String company = "CompanyA"; static{ System.out.println("staitc init"); } String position; Computer computer; public Programer() { this.position = "engineer"; this.computer = new Computer(); } public void working(){ System.out.println("coding..."); computer.working(); }}
说白了就是对其进行描述信息。所有的实例对象对这些仅仅引用一下就行
#2 = Utf8 com/jg/zhang/Programer //当前类的全限定名#4 = Utf8 com/jg/zhang/Person //父类的全限定名#5 = Utf8 company //company字段的名称#6 = Utf8 Ljava/lang/String; //company和position字段的描述符#7 = Utf8 position //position字段的名称#8 = Utf8 computer //computer字段的名称#9 = Utf8 Lcom/jg/zhang/Computer; //computer字段的描述符#10 = Utf8 <clinit> //类初始化方法(即静态初始化块)的方法名#11 = Utf8 ()V //working方法的描述符#12 = Utf8 Code //Code属性的属性名#14 = Utf8 CompanyA //程序中的常量字符串#19 = Utf8 java/lang/System //所引用的System类的全限定名#21 = Utf8 out //所引用的out字段的字段名#22 = Utf8 Ljava/io/PrintStream; //所引用的out字段的描述符#24 = Utf8 staitc init //程序中的常量字符串#27 = Utf8 java/io/PrintStream //所引用的PrintStream类的全限定名#29 = Utf8 println //所引用的println方法的方法名#30 = Utf8 (Ljava/lang/String;)V //所引用的println方法的描述符#31 = Utf8 LineNumberTable //LineNumberTable属性的属性名#32 = Utf8 LocalVariableTable //LocalVariableTable属性的属性名#33 = Utf8 <init> //当前类的构造方法的方法名#41 = Utf8 com/jg/zhang/Computer //所引用的Computer类的全限定名#45 = Utf8 this //局部变量this的变量名#46 = Utf8 Lcom/jg/zhang/Programer; //局部变量this的描述符#47 = Utf8 working //woking方法的方法名#49 = Utf8 coding... //程序中的字符串常量#52 = Utf8 SourceFile //SourceFile属性的属性名#53 = Utf8 Programer.java //当前类所在的源文件的文件名
package com.jg.zhang;public class Person { int age; int getAge(){ return age; }}
#1 = Class #2 // com/jg/zhang/Person #2 = Utf8 com/jg/zhang/Person #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Utf8 age #6 = Utf8 I #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Methodref #3.#11 // java/lang/Object."<init>":()V #11 = NameAndType #7:#8 // "<init>":()V #12 = Utf8 LineNumberTable #13 = Utf8 LocalVariableTable #14 = Utf8 this #15 = Utf8 Lcom/jg/zhang/Person; #16 = Utf8 getAge #17 = Utf8 ()I #18 = Fieldref #1.#19 // com/jg/zhang/Person.age:I #19 = NameAndType #5:#6 // age:I #20 = Utf8 SourceFile #21 = Utf8 Person.java
常量池里面的两种类型:
CONSTANT_Utf8_info -------------------字符串, 包括方法名, 字段名, 描述符
CONSTANT_NameAndType_info----------方法符号引用或字段的符号引用的一部分,也就是说, 如果在源文件中调用了一个方法, 或者引用了一个字段(不管是本类中的方法和字段, 还是引用其他类中的方法和字段), 那么和这个方法或在字段相对应的CONSTANT_NameAndType_info 就会出现在常量池中.如果只在当前类中定义了一个字段而不访问它, 或者定义了一个方法而不调用它, 那么常量池中就不会出现对应的CONSTANT_NameAndType_info 数据项.
CONSTANT_NameAndType_info 中引用了两个CONSTANT_Utf8_info, 一个叫做name_index, 存储方法名或字段名, 一个叫做descriptor_index, 存储方法描述符或字段描述符。
转自:http://blog.csdn.net/szwangdf/article/details/25616101