偃师论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6|回复: 0

[建议讨论] class是什么文件名(Class文件结构)

[复制链接]
发表于 2024-4-12 02:24:29 | 显示全部楼层 |阅读模式
Class 文件是由Java语言或者其他语言编译而得到的,然后再交给 JVM 去加载和执行。对于 Class 文件,我们可以通过文本编辑器查看它的 16 进制编码,然后分析它的组成构造。下面我们看一下 Class文件包含哪些模块:
  
       


  
        Class 文件结构
  
                对于Class字节码文件的查看,最初我们会用16进制的文本编辑器查看。但是这种方式并不常用,一般情况下我们会使用 javap -verbose XX.class 的命令来查看 Class结构。当然更好的方式是通过第三方工具(jclasslib)来查看。下面我们来详细的介绍一下具体的结构。
魔数
  
                魔数是 Class文件的 LOGO 标识。也就是当使用16进制文本编辑器查看Class文件时,开头的字符是:CAFEBABE。
版本号
  
                Class文件的版本号包含了:主版本号和次版本号。两个信息分别占用了2个字节的大小,并且紧跟在CAFEBABE(魔数)后面,依次为次版本号、主版本号。下面为用工具查看的结果:
  
       


  
        版本号
  
                下面列出了版本号和编译器版本的对应关系:
  
       


  
        版本号和编译器版本的对应关系
常量池
  
                常量池中的信息比较丰富,这个类中的基础信息都存放在里面。其中主要包含了:字面量(Literal)和符号引用(Symbolic References)两大类。主要包含了以下信息:
  • 类和接口的全限定名
  • 字段的名称和描述符
  • 方法的名称和描述符
      
                    在工具中查看的效果如下所示,其中我们从General Information中能看到常量池的大小是19,而Constant Pool中只有18个。这个是因为index为0的未展示出来,用作一些特殊处理使用。
      
           


      
            常量池
      
                    常量池的类型主要包含以下类型:
      
           


      
            常量池的类型
    访问标志
      
                    紧跟在常量池之后的就是访问标志(access_flags),这个标志用于识别一些类或者接口层次的信息。其中包括了:是类还是接口;是否定义为public;是否为abstract类型;是否为final等信息。具体的标志位和含义如下所示:
      
           


      
            访问标志
    当前类、父类和接口
      
                    紧跟着访问标志的是:当前类、父类和接口的信息,如下所示:
      
           


      
            当前类、父类和接口信息
    字段表集合
      
                    紧跟其后的是:类的属性字段信息。如下所示:
      
           


      
            类的属性字段信息
      
                    字段的访问权限标志如下表格所示:
      
           


      
            字段的访问权限标志
    方法表集合
      
                    方法表集合和字段表类似,依次包括了:访问标志(access_flags)、名称索引(name_index)、描述符索引(descriptor_index)、属性表集合(attributes)。如下图所示:
      
           


      
            方法表集合
      
                    对于方法表集合的访问标志,有如下表格:       
      
           


      
            方法表集合的访问标志
    属性表集合
      
                    这里面的属性代表的并不是Java类中的字段属性,而是Class文件、字段表、方法表表中各个模块所携带的属性。因为属性相对较多,使用的位置也不尽相同,下面只列举一下常见的一些属性。
      
           


      
            常见属性列表
      
            Code 属性
      
                    Code属性位于方法表的每个方法之中,其中包含了方法执行的字节码指令、异常处理等信息。如下所示:       
      
           


      
            Code 属性
      
            LineNumberTable 属性
      
                    该属性位于Code属性表中,存放了字节码指令对应到.java文件中的哪一行代码。如下图所示:
      
           


      
                    上图中的对应关系表示的是:字节码指令偏移地址为0的字节码,对应的代码行数是第8行。
      
            LocalVariableTable 属性
      
                    LocalVariableTable 属性用于描述栈帧中局部变量表的变量和Java源码中的变量之间的关系。它不是运行时必须的属性,可以通过 -g:none 或 -g:vars 来取消这项信息的生成。如果取消这部分信息,在IDE中的方法提示信息的入参的参数名称,将表现为arg0、arg1等字样。
      
            SourceFile 属性
      
                    SourceFile 属性用于记录生成 Class文件的源文件的名称。可选属性,可以通过 -g:none 或 -g:source 来开启/关闭生成。如下图所示:
      
           


      
            SourceFile 属性
      
            InnerClasses 属性
      
                    InnerClasses 属性用于记录内部类与宿主类之间的关联。如果一个类内部定义了内部类,就会产生 InnerClasses属性。如下所示:
      
           


      
            InnerClasses 属性
      
            Deprecated 属性
      
                    Deprecated属性可以用在类、方法、字段等结构中,用于表示类、方法、字段在未来的版本中有可能废弃。其中对于方法的废弃如下所示:
      
           


      
            Deprecated 属性
      
            总结
      
                    对于 Java字节码的构成,上面只是简单的介绍一下,仅仅是对于Class结构有个整体的认识。如果想要详细的了解 Class文件结构,请参阅《Java虚拟机规范(Java SE 8版)》。不过在日常的Class文件查看中,还是借助工具查看比较直接方便。
      
            参考:《深入理解Java虚拟机》
    ,
  • 您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|小黑屋|Archiver|手机版|偃师论坛

    GMT+8, 2024-4-30 06:00 , Processed in 0.144685 second(s), 17 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表