• class文件格式说明


    java代码编译成class文件之后,class文件里面的语法是什么样的,他的数据类型是什么以及如何存放的??

    class也是一种语言写的,只不过和我们的java语法不同而已。

    class文件就是把java文件转换成他自己的语法格式(类比把java的排序算法用C++写一样,仅仅是语法的不同而已)

    =====================================================================================================

    class文件时给虚拟机看的,所以比较紧凑,尽量减少存储空间

    对于一个java类,编译以后,使用另一种语法字节码表示,类是一个模板,要存储元数据信息,这些信息也需要占存储空间,(类名,访问属性,字段属性,字段名称,返回值以及方法名称,参数值,以及方法体),也就是说,编译基本确定了类元数据占用的信息,方法体执行的空间大小(栈深度)

    =====================================================================================================

    数据类型:基本单位为一个字节为单位:

      基本类型: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

  • 相关阅读:
    神马搜索 面试小结
    我的第一篇paper
    【转载】技巧:Vim 的纵向编辑模式
    实习求职小结
    将博客园界面打造成Hexo经典主题Light
    试一下Markdown
    四色标记算法
    射雕三部曲的优美片段
    Docker
    Sublime Text 3 文档
  • 原文地址:https://www.cnblogs.com/gstsyyb/p/3918066.html
Copyright © 2020-2023  润新知