精华内容
下载资源
问答
  • Class文件

    千次阅读 2018-08-19 19:21:10
    无关性 不同平台的Java虚拟机与所有平台都使用统一的程序存储...Java虚拟机不和包括Java在内的任何语言绑定,它只与Class文件关联,Class文件中包含了Java虚拟机指令集和符号表以及其他辅助信息,虚拟机并不关心C...

    无关性

    不同平台的Java虚拟机与所有平台都使用统一的程序存储格式字节码(ByteCode)来实现Java的平台无关性。此外,在Java虚拟机上也开发出了许多语言,包括Clojure、Groovy、JRuby、Jython、Scala等。Java虚拟机不和包括Java在内的任何语言绑定,它只与Class文件关联,Class文件中包含了Java虚拟机指令集和符号表以及其他辅助信息,虚拟机并不关心Class来源于何种语言。

    Class文件结构

    Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据。当遇到需要占用8位字节以上空间的数据项时,会按照高位在前的方式分割成若干个8位字节进行存储。Class文件采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构只有两种数据类型:无符号数和表。

    • 无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表一个字节、两个字节、四个字节和八个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。
    • 表是由多个无符号数或者其他表作为数据项构成的符合数据类型,所有表都以“_info”结尾,表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表。表内数据描述类的所有属性,数据项顺序、数量和字节序(Big-Endian)都是严格限定的。

    魔数与Class文件的版本

    每个Class文件开头的u4称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。Class文件的魔数为0xCAFEBABE。紧接着魔数的4个字节存储的是Class文件版本号,第5和第6是次版本号(Minor Version),第7和第8个字节是主版本号(Major Version),虚拟机不会执行超过其版本号的Class文件,但向下兼容。

    常量池

    主版本号之后是常量池入口,常量池是Class文件的资源仓库,它是Class文件结构中与其它项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时它还是在Class文件中第一个出现的表类型数据项目。常量池入口有一个u2记录常量池容量,容量为该数减一。常量池主要存放两大类常量:字面量(Literal)和符号引用(Symbolic Reference)。字面量包括文本字符串、final常量等。符号引用包括类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。

    Java代码在编译时,虚拟机加载Class文件进行动态连接,虚拟机运行时,要从常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址中。常量池中每一项常量都是一个表,表开始的第一位u1是标志位,代表常量属于哪种类型。

    使用jdk bin目录的javap可以查看Class文件字节码内容,下图是一个类的字节码,可以清楚的看到版本号、常量池等信息。

    这里写图片描述

    访问标志(access_flags)

    常量池之后是两个字节的访问标志,这个标志用于识别一些类或者接口层次的访问信息,包括这个类是类还是接口(ACC_INTERFACE)、是否是public(ACC_PUBLIC)等。如下图所示(ACC_SUPER在jdk1.0.2之后都为真):
    这里写图片描述

    类索引(this_class)、父类索引(super_class)与接口索引集合(interfaces)

    类索引和父类索引是两个u2,接口索引集合是一个u2的集合,类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名,因为可以实现多个接口,这些接口从左到右排列在接口集合中,都排在访问标志之后。

    类索引和父类索引指向一个类型为CONSTANT_Class_info的类描述符常量,通过类描述符常量的索引值找到定义在CONSTANT_Utf8_info类型的常量中的全限定名字符串。接口索引集合第一项为接口计数器。

    字段(field_info)表集合

    字段表集合用于描述接口或类中声明的变量,字段包括类级变量及实例级变量,但不包括在方法内部声明的局部变量。字段包括的信息有:字段作用域、可变性、数据类型等。字段表的具体结构是:access_flags、name_index、descriptor_index、attributes_count、attributes。

    方法表集合

    方法表的结构和字段表一样,方法里的代码存放在“Code”属性表里面,如果没有覆盖父类方法,就不会有父类额方法信息。要重载一个方法,要有与原方法不同的特征签名,代码的特征签名是一个方法中各个参数在常量池中的字段符合引用的集合。因为返回值不包含在特征签名中,所以无法只靠返回值不同来让函数重载。字节码的特征签名还包括方法返回值和受查异常表,所以如果两个函数名称和特征签名相同,返回值不同,也可以存在于一个Class文件中,Java代码里就不能了。

    属性表(attribute_info)集合

    Class文件、字段表、方法表都可以携带自己的属性表集合,用于描述某些场景专有的信息。

    属性表中包括Code、ConstantValue、LocalVariableTable等。下图为一个方法表中的属性表:
    这里写图片描述

    没有参数的方法的args_size=1,这是因为编译器把对this关键字的访问转换为对一个普通方法参数的访问,因此至少有一个指向当前对象的局部变量,只对示例方法有效,如果是static方法就为0。


    异常表会为try…catch..finally生成三条异常记录,分别对应三种情况:

    • 如果try语句块出现属于Exception或其子类的异常,转到catch语句块处理;
    • 如果try语句块出现不属于Exception或其异常的子类,转到finally语句块处理;
    • 如果catch语句块未出现任何异常,转到finally语句块处理。
    展开全文
  • Class文件结构

    万次阅读 2020-08-04 14:06:53
    Class文件结构 Java技术能够一直保持非常好的向后兼容性,这点Class文件结构的稳定性功不可没。Java目前已经发展到JDK14,但是class文件结构的内容,绝大部分在JDK1.2时代就已经定义好了。虽然JDK1.2的内容比较古老...

    Class文件结构

    Java技术能够一直保持非常好的向后兼容性,这点Class文件结构的稳定性功不可没。Java目前已经发展到JDK14,但是class文件结构的内容,绝大部分在JDK1.2时代就已经定义好了。虽然JDK1.2的内容比较古老,但是java发展经历了十余个大版本,但是每次基本上只是在原有结构基础上新增内容、扩充功能,并未对定义的内容做修改。

    Class文件是一组以8位字节为基础单位的二进制流(实际上任何文件都是以二进制流形式存在的)。

    工欲善其事,必先利其器。下面先介绍几个实用的工具。

    工具介绍

    Sublime/HexView:用来查看文件的16进制内容。

    javap:JDK自带的反编译工具。能将.class字节码文件解析成可读的文件格式。

    jclasslib:在javap的基础上提供了可视化界面,能够更加直观的查看字节码中的内容。它还分门别类的对类中的各个部分进行了整理,非常的人性化。同时,它还提供了Idea的插件,你可以从plugins中搜索到它。

    Class文件格式

    演示代码:

    package com.morris.jvm.bytecode;
    
    public class ByteCode {
    }
    

    对应的字节码如下:

    cafe babe 0000 0034 0010 0a00 0300 0d07
    000e 0700 0f01 0006 3c69 6e69 743e 0100
    0328 2956 0100 0443 6f64 6501 000f 4c69
    6e65 4e75 6d62 6572 5461 626c 6501 0012
    4c6f 6361 6c56 6172 6961 626c 6554 6162
    6c65 0100 0474 6869 7301 0022 4c63 6f6d
    2f6d 6f72 7269 732f 6a76 6d2f 6279 7465
    636f 6465 2f42 7974 6543 6f64 653b 0100
    0a53 6f75 7263 6546 696c 6501 000d 4279
    7465 436f 6465 2e6a 6176 610c 0004 0005
    0100 2063 6f6d 2f6d 6f72 7269 732f 6a76
    6d2f 6279 7465 636f 6465 2f42 7974 6543
    6f64 6501 0010 6a61 7661 2f6c 616e 672f
    4f62 6a65 6374 0021 0002 0003 0000 0000
    0001 0001 0004 0005 0001 0006 0000 002f
    0001 0001 0000 0005 2ab7 0001 b100 0000
    0200 0700 0000 0600 0100 0000 0300 0800
    0000 0c00 0100 0000 0500 0900 0a00 0000
    0100 0b00 0000 0200 0c
    

    各个数据项严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。

    Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表。

    无符号数属于基本的数据类型,以 u1、u2、u4、u8 来分别代表1个字节(一个字节是由两位16进制数组成)、2个字节、4个字节和8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。

    表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表都习惯性地以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表,它由下面几个部分组成:

    类型名称解释数量
    u4magic魔数1
    u2minor_version次版本号1
    u2major_version主版本号1
    u2constant_pool_count常量池常量个数1
    constant_pool_infoconstant_pool常量池constant_pool_count -1
    u2access_flags访问标记1
    u2this_class类索引1
    u2superclass父类索引1
    u2interfaces_count接口索引数量1
    u2interfaces接口内容interfaces_count
    u2field_count字段表字段数量1
    field_infofields字段表field_count
    u2methods_count方法表方法数量1
    method_infomethods方法表methods_count
    u2attributes_count属性表属性数量1
    attribute_infoattributes属性表attributes_count

    魔数与版本号

    每个Class文件的头4个字节0xcafe babe称为魔数(Magic Number),它的作用是确定这个文件是否为一个能被虚拟机接受的Class文件。使用魔数而不是扩展名来进行识别主要是基于安全方面的考虑,因为文件扩展名可以随意地改动。

    紧接着魔数后的4个字节存储的是Class文件的版本号:第5、6个字节是次版本号(Minor Version),第7、8个字节是主版本号(Major Version)。Java的版本号是从45开始的,JDK 1.1之后的每个JDK大版本发布,主版本号向上加1,高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件,即使文件格式并未发生任何变化,虚拟机也必须拒绝执行超过其版本号的Class文件。

    0x0000表示次版本号为0,0x0034表示主版本号为52,也就是JDK1.8。

    下表列出了各个版本JDK的十六进制版本号信息:

    JDK版本次版本号主版本号十进制
    JDK1.10000002D45
    JDK1.20000002E46
    JDK1.30000002F47
    JDK1.40000003048
    JDK1.50000003149
    JDK1.60000003250
    JDK1.70000003351
    JDK1.80000003452

    常量池

    常量池中常量的数量是不固定的,所以在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值(constant_pool_count)。与Java中语言习惯不一样的是,这个容量计数是从1而不是0开始的。

    常量池中主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References)。

    字面量比较接近于Java语言层面的常量概念,如文本字符串、声明为final的常量值等。

    而符号引用则属于编译原理方面的概念,包括了三类常量:类和接口的全限定名(Fully Qualified Name)、字段的名称和描述符(Descriptor)、方法的名称和描述符。

    0x0010表示有15个常量(从1开始计数),15个常量的内容如下。

       #1 = Methodref          #3.#13         // java/lang/Object."<init>":()V
       #2 = Class              #14            // com/morris/jvm/bytecode/ByteCode
       #3 = Class              #15            // java/lang/Object
       #4 = Utf8               <init>
       #5 = Utf8               ()V
       #6 = Utf8               Code
       #7 = Utf8               LineNumberTable
       #8 = Utf8               LocalVariableTable
       #9 = Utf8               this
      #10 = Utf8               Lcom/morris/jvm/bytecode/ByteCode;
      #11 = Utf8               SourceFile
      #12 = Utf8               ByteCode.java
      #13 = NameAndType        #4:#5          // "<init>":()V
      #14 = Utf8               com/morris/jvm/bytecode/ByteCode
      #15 = Utf8               java/lang/Object
    

    对应的二进制内容如下:

    0a 0003 000d // Methodref #3 #13
    07 000e // Class # 14
    07 000f // Class #15
    01 0006 3c696e69743e // Utf8 <init>
    01 0003 282956 // Utf8 ()V
    01 0004 436f6465 // Utf8 Code
    01 000f 4c696e654e756d6265725461626c65 // Utf8 LineNumberTable
    01 0012 4c6f63616c5661726961626c655461626c65 // Utf8 LocalVariableTable
    01 0004 74686973 // Utf8 this
    01 0022 4c636f6d2f6d6f727269732f6a766d2f62797465636f64652f42797465436f64653b // Utf8 Lcom/morris/jvm/bytecode/ByteCode;
    01 000a 536f7572636546696c65 // Utf8 SourceFile
    01 000d 42797465436f64652e6a617661 // Utf8 ByteCode.java
    0c 0004 0005 // NameAndType #4 #5
    01 0020 636f6d2f6d6f727269732f6a766d2f62797465636f64652f42797465436f6465 // Utf8 com/morris/jvm/bytecode/ByteCode
    01 0010 6a6176612f6c616e672f4f626a656374 // Utf8 java/lang/Object
    

    在这里插入图片描述

    访问标志

    用于识别一些类或者接口层次的访问信息,包括:这个Class是类还是接口;是否定义为public类型;是否定义为abstract类型;如果是类的话,是否被声明为final等。

    0x0021表示ACC_SUPPER和ACC_PUBLIC标志位为1。

    具体的标志位以及标志的含义见下表:

    标志名称标志值含义
    ACC_PUBLIC0x0001是否为public类型
    ACC_FINAL0x0010是否被声明为final,只有类可设置
    ACC_SUPER0x0020是否允许使用invokespedal字节码指令的新语义,invokespecial指令的语义在JDK1.2发生过改变,为了区别这条指令使用哪种语义,JDK1.2之后编译出来的类的这个标志都必须为真
    ACC_INTERFACE0x0200标识这是一个接口
    ACC_ABSTRACT0x0400是否为abstract类型,对于接口或抽象类来说,此标志值为真,其他类值为假
    ACC_SYNTHETIC0x1000标识这个类并非由用户代码产生的
    ACC_ANNOTATION0x2000标识这是一个注解
    ACC_ENUM0x4000标识这是一个枚举

    类索引、父类索引与接口索引集合

    这三项数据来确定这个类的继承关系。类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。由于Java语言不允许多重继承,所以父类索引只有一个,除了java.lang.Object之外,所有的Java类都有父类,因此除了java.lang.Object外,所有Java类的父类索引都不为0。接口索引集合就用来描述这个类实现了哪些接口,这些被实现的接口将按implements语句(如果这个类本身是一个接口,则应当是extends语句后的接口顺序从左到右排列在接口索引集合中。

    0x0002表示类的索引为#2。

    0x0003表示父类的索引为#3。

    0x0000表示类没有实现任何接口。

    字段表集合

    描述接口或者类中声明的变量。字段(field)包括类级变量以及实例级变量。而字段叫什么名字、字段被定义为什么数据类型,这些都是无法固定的,只能引用常量池中的常量来描述。

    字段表集合中不会列出从超类或者父接口中继承而来的字段,但有可能列出原本Java代码之中不存在的字段,譬如在内部类中为了保持对外部类的访问性,会自动添加指向外部类实例的字段。

    0x0000表示类的字段个数为0。

    字段表的每个字段用一个名为field_info的表来表示,field_info表的数据结构如下所示:

    类型名称数量含义
    u2access_flags1字段访问标识
    u2name_index1字段名称索引项
    u2descriptor_index1字段描述符索引项
    u2attributes_count1属性表计数器
    attribute_infoattributesattribute_count属性表

    方法表集合

    描述了方法的定义,但是方法里的Java代码,经过编译器编译成字节码指令后,存放在属性表集合中的方法属性表集合中一个名为“Code”的属性里面。与字段表集合相类似的,如果父类方法在子类中没有被重写(Override),方法表集合中就不会出现来自父类的方法信息。但同样的,有可能会出现由编译器自动添加的方法,最典型的便是类构造器“<clinit>”方法和实例构造器“<init>”。

    0x0001表示方法的个数。

    0x0001表示方法的访问标识,ACC_PUBLIC。

    0x0004表示方法名的索引为#4。

    0x0005表示方法的描述符的索引为#5,也就是参数和返回值。

    方法表中的每个方法都用一个method_info表示,其数据结构如下:

    类型名称数量含义
    u2access_flags1方法访问标识
    u2name_index1方法名称索引项
    u2descriptor_index1方法描述符索引项
    u2attributes_count1属性表计数器
    attribute_infoattributesattribute_count属性表

    存储Class文件、字段表、方法表都自己的属性表集合,以用于描述某些场景专有的信息。如方法的代码就存储在Code属性表中。

    0x0001表示属性表的计数为1。

    属性表的表结构如下:

    类型名称数量
    u2attribute_name_index1
    u4attribute_length1
    u1attribute_infoattribute_length

    Code 属性的表结构如下:

    类型名称数量
    u2attribute_name_index1
    u4attribute_length1
    u2max_stack1
    u2max_locals1
    u4code_length1
    u1codecode_length
    u2exception_table_length1
    exception_infoexception_tableexception_table_length
    u2attributes_count1
    attribute_infoattributesattributes_count

    0x0006对应常量池中的索引为6,Code。

    0x0000 0x002f表示属性表的长度为2f。

    0x0001表示操作数栈的最大深度为1。

    0x0001表示本地变量表的槽slot数量为1。

    0x0000 0005表示字节码的长度为5。

    0x2a对应的字节码指令为aload_0,将本地变量表的第一个值push到栈顶。

    0xb7 0001对应的字节码指令为invokespecial #1 <java/lang/Object.<init>>,调用父类的构造方法。

    0xb1对应的字节码指令为return,将栈顶的值返回。

    0x0000表示异常表的数量。

    0x0002表示属性表的长度。

    属性表的表结构如下:

    类型名称数量
    u2attribute_name_index1
    u4attribute_length1
    u1attribute_infoattribute_length

    0x0007表示属性名的索引为#7,LineNumberTable。

    0x00000006表示属性长度为6个字节。

    0x0001表示LineNumberTable的长度为1。

    LineNumberTable表的表结构如下图所示:

    类型名称数量
    u2attribute_name_index1
    u4attribute_length1
    u2line_number_table_length1
    line_number_infoline_number_tableline_number_table_length

    接着跟着1个line_number_info类型的数据,下面是line_number_info表的结构,其包含了start_pc和line_number两个u2类型的数据项。前者是字节码行号,后者是Java源码行号。

    类型名称数量
    u2start_pc1
    u2line_number1

    0x0000 :start_pc,字节码行号。
    0x0003:line_number,Java源码行号。

    接下来是局部变量表:

    类型名称数量
    u2attribute_name_index1
    u4attribute_length1
    u2local_variable_table_length1
    local_variable_infolocal_variable_tablelocal_variable_table_length

    0x0008表示属性名的索引为#8,LocalVariableTable。
    0x0000000c表示局部变量表的长度为12。

    local_variable_info的结构:

    类型名称数量
    u2start_pc1
    u2length1
    u2name_index1
    u2descriptor_index1
    u2index1

    0x0001表示局部变量的个数。

    0x0000表示这个局部变量生命周期开始的字节码偏移量。

    0x0005表示这个局部变量作用范围的长度。

    0x0009表示这个局部变量的名称的索引为#9,也就是this。

    0x000a表示这个局部变量的描述符的索引为#10,对应为Lcom/morris/jvm/bytecode/ByteCode。

    0x0000表示这个局部变量在局部变量表中槽的位置。

    属性表集合

    最后一个就是属性表集合。

    0x0001表示属性表的长度为1。

    接下来是SourceFile,SourceFile属性的表结构如下:

    类型名称数量
    u2attribute_name_index1
    u4attribute_length1
    u2sourcefile_infoattribute_length

    0x000b表示属性名称的索引为#11,也就是SourceFile。

    0x00000002表示属性长度为2。

    0x000c表示SourceFil 的常量池索引,即该字节码文件的源文件名称ByteCode.java。

    更多精彩内容关注本人公众号:架构师升级之路
    在这里插入图片描述

    展开全文
  • 关于Class文件

    千次阅读 2016-06-06 12:11:09
    什么是Class文件Java人对class文件肯定很熟悉了,它是Java源码编译后的产物。JVM运行时负责加载class文件,并根据class定义的执行逻辑运行。java为了将硬件底层的差异屏蔽掉,引入了Java虚拟机(JVM)并将硬件差异...

    什么是Class文件

    Java人对class文件肯定很熟悉了,它是Java源码编译后的产物。JVM运行时负责加载class文件,并根据class定义的执行逻辑运行。java为了将硬件底层的差异屏蔽掉,引入了Java虚拟机(JVM)并将硬件差异处理都放到JVM中,所以可以编译出统一的二进制文件——class。所以只要通过编译器编译成规范的class文件都可以在JVM上面运行,像现在很多其他语言其实都是编译成class文件并运行在JVM上,例如Scala、JRuby、Groovy、Clojure等等。

    class字节码作为java虚拟机的语言,java虚拟机规范规定了class文件的结构,JVM运行时类加载器就会对这些class字节码进行加载。这里并不深入讨论JVM对于class字节码的处理,而是主要了解class文件的结构,因为tomcat的实现涉及到了class相关知识。

    Class文件结构

    每个class文件包含一个类或者接口的Java类型,class文件以8位字节为基础的二进制流,每个数据项的顺序和占用字节数都有严格的规定。一个class文件的基本结构如下:

    ClassFile{
    u4 magic;
    u2 minor_version;
    u2 major_version;
    u2 constant_pool_count;
    cp_info constant_pool[constant_pool_count-1]
    u2 access_flags;
    u2 this_class;
    u2 super_class;
    u2 interfaces_count;
    u2 interfaces[interfaces_count];
    u2 fields_count;

    展开全文
  • Class文件结构分析

    万次阅读 2019-04-28 17:18:03
    Class文件结构分析 1. Class文件的结构概览图 2. 每一项数据说明 类型 名称 数量 说明 u4 magic 1 魔数:确定一个文件是否是Class文件 u2 minor_version 1 Class文件的次版本号 u2 major_version 1 ...

    Class文件结构分析

    1. Class文件的结构概览图

    在这里插入图片描述

    2. 每一项数据说明

    类型名称数量说明
    u4magic1魔数:确定一个文件是否是Class文件
    u2minor_version1Class文件的次版本号
    u2major_version1Class文件的主版本号:一个JVM实例只能支持特定范围内版本号的Class文件(可以向下兼容)。
    u2constant_pool_count1常量表数量
    cp_infoconstant_poolconstant_pool_count-1常量池:以理解为Class文件的资源仓库,后面的其他数据项可以引用常量池内容。
    u2access_flags1类的访问标志信息:用于表示这个类或者接口的访问权限及基础属性。
    u2this_class1指向当前类的常量索引:用来确定这个类的的全限定名。
    u2super_class1指向父类的常量的索引:用来确定这个类的父类的全限定名。
    u2interfaces_count1接口的数量
    u2interfacesinterfaces_count指向接口的常量索引:用来描述这个类实现了哪些接口。
    u2fields_count1字段表数量
    field_infofieldsfields_count字段表集合:描述当前类或接口声明的所有字段。
    u2methods_count1方法表数量
    method_infomethodsmethods_count方法表集合:只描述当前类或接口中声明的方法,不包括从父类或父接口继承的方法。
    u2attributes_count1属性表数量
    attributes_infoattributesattributes_count属性表集合:用于描述某些场景专有的信息,如字节码的指令信息等等。

    3. Class文件16进制解析

    3.1 魔数。
    • Class文件开始是4个字节定义为魔数(Magic Number);
    • 唯一作用:确定一个文件是否是Class文件;
    • 魔数可以自由选择,只要没有广泛使用而且不会引起混淆的即可,这样就不会因为扩展名改变而无法识别;其他许多文件类型格式头都存在魔数,如gif、jpeg等
    • Class文件的魔数为"0xCAFEBABE"(咖啡宝贝),比照ClassFileTest.class如下:
    3.2 方法表解析
    • public void bar()
    00 01 访问控制符 public 
    00 11 这里11是16进制转10进制为17,对应 Constant pool: #17 = Utf8 bar
    00 0b 描述符0b是16进制转10进制为11,对应 Constant pool: #11 = Utf8 ()V
    翻译过来:public void bar()
    
    00 01 表示有1个属性表attribute_count
    属性表attribute_info(u2,u4,u1*length)
    00 0c 表示attribute_name_index,索引,这里0c是16进制转10进制为12,对应 Constant pool: #12 = Utf8 Code
    00 00 00 38 表示attribute_length,代码占的大小,这里38是16进制转10进制为56,表示bar()方法占了56个字节
    
    00 02 表示max_stack最大栈深是2
    00 01 表示max_locals最大变量数是1
    00 00 00 0a 表示code_length代码行数,这里0a是16进制转10进制为10
    
    args_size 方法的参数有多少个(默认是this,如果方法是static那么就是0)
    
    对应字节码
       00 02 00 01 00 00 00 0a b2 00 02 b2 00 03 b6 
    00 04 b1 00 00 00 02 00 0d 00 00 00 0a 00 02 00 
    00 00 0f 00 09 00 10 00 0e 00 00 00 0c 00 01 00 
    00 00 0a 00 0f 00 10 00 00  
    
    b2 getstatic
    00 nop
    03 iconst_0
    b6 invokevirtual
    04 iconst_1
    
    本地行号表
    LineNumberTable:
            line 15: 0
            line 16: 9
    
    本地变量表
    LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      10     0  this   Lcom/cecjx/TestM;
    Start+Length 表示一个本地变量的作用域(0对应行是15,10对应行是17||即表示在该方法中,该变量的作用范围是15行到17行)
    Slot 表示几个槽存储
    Name 表示简单名字
    
    签名
    Signature
    伪泛型。
    

    在这里插入图片描述

    • 静态变量初始化
     static {};
        descriptor: ()V
        flags: ACC_STATIC
        Code:
          stack=1, locals=0, args_size=0
             0: iconst_2
             1: putstatic     #3                  // Field m:I
             4: return
          LineNumberTable:
            line 12: 0
    

    在这里插入图片描述

    展开全文
  • class文件查看工具

    热门讨论 2010-04-22 10:54:47
    如果想看看被编译后的.class文件,而又不想要反编译文件,这是很不错的工具喔!占用空间小,操作简单,就一个文件解决您的class文件查看问题……它的好处只有用了才体会得到!
  • class文件和dex文件

    千次阅读 2018-08-17 17:06:28
    Class文件 1、什么是class文件 能够被JVM识别,加载并执行的文件格式。 2、class文件的生成 ![这里写图片描述]...
  • class文件转java文件

    千次阅读 2019-09-02 14:54:49
    class文件转java文件 有时候需要进行class 反编译java 第一步: 第二步: 第三步: src 是编译之后的java 源码
  • Java虚拟机中定义的Class文件格式。每一个Class文件都对应着唯一一个类或接口的定义信息,但是相对地,类或接口并不一定都得定义在文件里(譬如类或接口也可以通过类加载器直接生成)。我们只是通俗地将任意一个有效...
  • JVM进阶(十八)——初识Class文件

    万次阅读 2017-03-13 15:54:10
    JVM进阶(十八)——初识Class文件  关于类加载机制的相关知识在前面的博文中暂时先讲那么多。中间留下了很多问题,从本篇博文开始,我们来一一解决。   从我们最陌生而又最熟悉的.class文件开始说起。.class文件...
  • JVM进阶(十九)——Class文件常量池

    万次阅读 2017-03-13 16:20:55
    JVM进阶(十九)——Class文件常量池  在上一博文《JVM进阶(十八)——初识Class文件》中,我们了解了Class文件的一些基础知识。他的整个内部结构就是一张很大的表,我们就是从这张表入手,一一分析每个部分的结构。...
  • 015-JVM-使用javap查看class文件内容

    万次阅读 2020-12-20 15:08:09
    上一篇:014-JVM-查看class文按键的工具...处理使用上面的工具还可以使用javap查看class文件的格式 1. 使用javap -v 查看Helloworld.class文件 Microsoft Windows [版本 10.0.19041.685] (c) 2020 Microsoft Corporatio
  • 有时候我们需要根据class文件获取class的内部信息,比如class的完整类名,方法等。注意啊,反射此处貌似行不通,因为只有class文件,不知道类名的。。。 但,我们知道class文件是有规范的,既然有规范,那肯定可以...
  • Class文件格式实战:使用ASM动态生成class文件

    万次阅读 多人点赞 2014-04-05 13:24:09
    众所周知, JVM在运行时, 加载并执行class文件, 这个class文件基本上都是由我们所写的java源文件通过javac编译而得到的。 但是, 我们有时候会遇到这种情况:在前期(编写程序时)不知道要写什么类, 只有到运行...
  • 014-JVM-Class文件结构概况

    万次阅读 2020-12-20 14:38:51
    我们写了一个HelloWorld.java,然后通过javac编译出一个HelloWorld.class文件,那么这些类似的class文件中都存有那些东西呢? 下面给出答案: 1. Class文件结构概况 下图有点模糊,可以直接访问查看源脑图: ...
  • 首先,加密和加密的大致思想是:加密无非就是对加密后的class文件进行异或一下,解密呢,那就是再对class文件异或回来即可。 加密后的文件如果想要用到的话,就需要classLoader动态加载进来,具体实现为: /...
  • JVM基础知识(三)Class文件解析实例

    万次阅读 2021-05-15 17:43:05
    用一段示例代码来解析Class文件。 一、源码 package com.yhcookie.cxt.mytest; public class Test01_ByteCode { public Test01_ByteCode(){}; } 二、对应的Class文件(16进制) CA FE BA BE 00 00 00 34 00 10 ...
  • cmd 编译class 文件

    千次阅读 2018-07-16 10:41:14
    1、打开cmd 快捷键:ctrl+R2、进入要编译的文件所在的目录3、dir xxx.java 查看文件4、编译 javac xxx.java 5、查看编译文件所在的目录下有没有xx.class 文件...
  • 【JVM】类文件(class文件)结构

    千次阅读 2021-04-28 15:33:07
    Class文件格式采用类似C语言结构体的伪结构来存储数据,这种结构只有两种数据类型:无符号数和表。 1 魔数 确定这个文件是否为一个能被虚拟机接收的 class 文件。 如果一个文件不是以0xCAFEBABE开头,那它就肯定...
  • MyEclipse反编译Class文件工具

    千次下载 热门讨论 2013-06-08 10:08:29
    很使用的反编译Class文件的工具,反编译之后就可以查看class的源代码
  • Class文件 反编译成 Java文件

    万次阅读 2020-09-16 16:28:30
    准备 首先得先安装了JDK,并且配置了环境变量。 然后去jdk目录下的bin文件夹中查看是否存在jad.exe。 没有的话请先下载一个jad.exe,放到... 跳转到你需要进行反编译的class文件的存放地址。 输入:jad -s...
  • Class文件格式总结

    千次阅读 热门讨论 2014-03-29 01:59:51
    到此, 所有关于class文件格式的重要内容都已经讲解完了, 不敢说面面俱到, 但是敢说大部分重要的内容都包含在内了。前前后后用了9篇博客来专门讲解class文件结构, 为什么花那么多的时间和精力来介绍class文件呢?...
  • class文件运行过程

    千次阅读 2018-08-13 12:30:36
    当源文件(.java文件)被编译成.class文件,且经过合法检测后,.class的运行过程如下: 依图中FirstStatic.class文件为例: 1)FirstStatic.class文件首先进入方法去,将.class文件中的静态的东西放入静态区属于...
  • 016-JVM-十六进制class文件简单解读

    万次阅读 2020-12-20 21:40:01
    2.class文件 注意:默认编译后会有个无惨的构造方法 // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yuhl; public class T0100_B
  • 这个软件兼容很多文件格式,但对java编译后的.class文件就不听话,出现乱码,无论你更换怎样的编码格式,还是乱码,这时你需要插件才能解决这个问题,插件下载也是有要求,对应版本要下载对应的插件,不然就回出现...
  • java运行class文件或jar文件

    千次阅读 2017-05-16 17:38:10
    当需要用命令行运行一个class文件或者jar文件时,经常会报各种错误,这里总结一下操作需要注意的东西。 classpath 运行class文件上时,java会从classpath去寻找对应的class,这时如果目录不包含要运行的class所在的...
  • 反编译class文件,一种最简单方法

    万次阅读 多人点赞 2019-04-23 19:54:19
    今天突然需要反编译一下以前的一个class文件,确定一下是否与源码一种,在网上找了一些方法,发现比较复杂。 自己无意间发现的一种简单方法,分享给大家。 就是把class文件,拖拽到IntelliJ IDEA工具中,IntelliJ...
  • 读完本文,你将会学到: 1、类中定义的field字段是如何在class文件中组织的 2、不同的数据类型在class文件中是如何表示的 3、static final类型的field字段的初始化赋值问题
  • 最通俗易懂的Class文件结构(上)

    万次阅读 多人点赞 2019-11-19 08:52:42
    一般对于数据结构的分享难免比较枯燥,但是了解Class文件结构是了解Java虚拟机的重要基础之一。如果想比较深入地了解Java虚拟机,那么Class文件结构是不能不接触的。我会力求在保证逻辑准确的基础上,尽量通俗易懂地...
  • Jar包中Class文件替换

    千次阅读 2020-08-05 15:09:58
    说明:本文是已经对java文件进行编译了之后,已经形成了class文件,在这里只涉及用class文件直接替换jar包里面的class文件 Ps: 至于如何拿出jar包的class文件,反编译修改改文件后又重新编译,再放入原文件重新打jar...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,776,078
精华内容 1,510,431
关键字:

class文件