<div class="htmledit_views" id="content_views">
<div id="article_content" class="article_content"> <p><span style="font-family:'Comic Sans MS';"><strong>[last updated: 2014/11/19 09:06] </strong> </span> <span style="font-family:'Microsoft YaHei';"></span><span style="font-family:'Microsoft YaHei';font-size:12px;"><br></span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> 作为Java程序猿,我们知道,我们写好的.java 源代码,最后会被Java编译器编译成后缀为.class的文件,该类型的文件是由字节组成的文件,又叫字节码文件。那么,class字节码文件里面到底是有什么呢?它又是怎样组织的呢?让我们先来大概了解一下他的组成结构吧。</span><br></p> <p><img src="https://img-blog.csdn.net/20141008125149484?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHVhbmxvdWlz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""></p> <p><br></p> <fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO1</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';"> 魔数(<span style="font-family:'Comic Sans MS';">magic</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> 所有的由Java编译器编译而成的class文件的前4个字节都是“0xCAFEBABE” <br> 它的作用在于:当JVM在尝试加载某个文件到内存中来的时候,会首先判断此class文件有没有JVM认为可以接受的“签名”,即JVM会首先读取文件的前4个字节,判断该4个字节是否是“0xCAFEBABE”,如果是,则JVM会认为可以将此文件当作class文件来加载并使用。</span><br></p> </fieldset><p><br></p> <fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO2</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">版本号(<span style="font-family:'Comic Sans MS';">minor_version,major_version</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> </span><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';">随着Java本身的发展,Java语言特性和JVM虚拟机也会有相应的更新和增强。目前我们能够用到的JDK版本如:1.5,1.6,1.7,还有现如今最新的1.8。发布新版本的目的在于:在原有的版本上增加新特性和相应的JVM虚拟机的优化。而随着主版本发布的次版本,则是修改相应主版本上出现的bug。我们平时只需要关注主版本就可以了。</span></span></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';">主版本号和次版本号在class文件中各占两个字节,副版本号占用第5、6两个字节,而主版本号则占用第7,8两个字节。JDK1.0的主版本号为45,以后的每个新主版本都会在原先版本的基础上加1。若现在使用的是JDK1.7编译出来的class文件,则相应的主版本号应该是51,对应的7,8个字节的十六进制的值应该是 0x33。</span></span></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"> 一个 JVM实例只能支持特定范围内的主版本号 (<span style="font-family:'Comic Sans MS';">Mi</span> 至<span style="font-family:'Comic Sans MS';">Mj</span>) 和 0 至特定范围内 (0 至 m) 的副版本号。假设一个 Class 文件的格式版本号为<span style="font-family:'Comic Sans MS';"> V</span>, 仅当<span style="font-family:'Comic Sans MS';"><strong>Mi.0 ≤ v ≤ Mj.m</strong></span>成立时,这个 Class 文件才可以被此 Java 虚拟机支持。不同版本的 Java 虚拟机实现支持的版本号也不同,高版本号的 Java 虚拟机实现可以支持低版本号的 Class 文件,反之则不成立。</span></span></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"> JVM在加载class文件的时候,会读取出主版本号,然后比较这个class文件的主版本号和JVM本身的版本号,如果JVM本身的版本号 < class文件的版本号,JVM会认为加载不了这个class文件,会抛出我们经常见到的<span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';">"<span style="color:#FF0000;">java.lang.UnsupportedClassVersionError: Bad version number in .class file</span> "</span></span> <strong>Error 错误</strong>;反之,JVM会认为可以加载此class文件,继续加载此class文件。</span></span><br></span></span></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"> <br></span></span></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"> <span style="font-family:'KaiTi_GB2312';"> <span style="font-size:14px;color:#FF6600;"><strong>小贴士:</strong></span></span></span></span></p> <blockquote> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';">1. 有时候我们在运行程序时会抛出这个<span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"><strong>Error 错误</strong></span></span></span></span>:"<span style="font-family:'Comic Sans MS';"><span style="color:#FF0000;"><em>java.lang.UnsupportedClassVersionError: Bad version number in .class file</em></span></span>"。上面已经揭示了出现这个问题的原因,就是在于当前尝试加载class文件的JVM虚拟机的版本 低于class文件的版本。解决方法:1.重新使用当前jvm编译源代码,然后再运行代码;2.将当前JVM虚拟机更新到class文件的版本。</span></span></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';">2. 怎样查看class文件的版本号?</span></span></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"> 可以借助于文本编辑工具,直接查看该文件的7,8个字节的值,确定class文件是什么版本的。<br></span></span></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';">当然快捷的方式使用JDK自带的javap工具,如当前有Programmer.class 文件,进入此文件所在的目录,然后执行 ”<span style="font-family:'Comic Sans MS';"><strong>javap -v Programmer</strong></span>“,结果会类似如下所示:</span></span></p> <p><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';"><img src="https://img-blog.csdn.net/20141009113052452?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHVhbmxvdWlz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""></span></span> <br></p> </blockquote> </fieldset><p><br></p> <p><br></p> <fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO3</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">常量池计数器(<span style="font-family:'Comic Sans MS';">constant_pool_count</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> 常量池是class文件中非常重要的结构,它描述着整个class文件的字面量信息。 </span><span style="font-family:'Microsoft YaHei';font-size:12px;">常量池是由一组<span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool</span>结构体数组组成的,而数组的大小则由常量池计数器指定。常量池计数器<span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool_count</span> 的值 =<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool</span></span>表中的成员数+ 1。<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool</span></span>表的索引值只有在大于 0 且小于<span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool_count</span>时才会被认为是有效的。</span><br></p> </fieldset><fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO4</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">常量池数据区(<span style="font-family:'Comic Sans MS';">constant_pool[contstant_pool_count-1]</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">常量池,<span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool</span>是一种表结构,它包含 Class 文件结构及其子结构中引用的所有字符串常量、 类或接口名、字段名和其它常量。 常量池中的每一项都具备相同的格式特征——第一个字节作为类型标记用于识别该项是哪种类型的常量,称为 “<span style="font-family:'Comic Sans MS';color:#FF6600;">tag byte</span>” 。常量池的索引范围是 1 至<span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool_count−1</span>。常量池的具体细节我们会稍后讨论。</span></p> </fieldset><p><br></p> <fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO6</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">访问标志(<span style="font-family:'Comic Sans MS';">access_flags</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> 访问标志,<span style="font-family:'Comic Sans MS';color:#FF6600;">access_flags</span> 是一种掩码标志,用于表示某个类或者接口的访问权限及基础属性。</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> <img src="https://img-blog.csdn.net/20141009130149170?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHVhbmxvdWlz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""><br></span></p> <br></fieldset><p><br></p> <p><br></p> <fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO7</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">类索引(<span style="font-family:'Comic Sans MS';">this_class</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> </span><span style="font-family:'Microsoft YaHei';font-size:12px;"></span><span style="font-family:'Microsoft YaHei';font-size:12px;">类索引,<span style="font-family:'Comic Sans MS';color:#FF6600;">this_class</span>的值必须是对<span style="font-family:'Comic Sans MS';"><span style="color:#FF6600;">constant_pool</span></span>表中项目的一个有效索引值。<span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool</span>表在这个索引处的项必须为<span><span style="color:#FF6600;"><span style="font-family:'Comic Sans MS';">CONSTANT_Class_info</span></span></span> 类型常量,表示这个 Class 文件所定义的类或接口。</span><br></p> </fieldset><p><br></p> <p><br></p> <fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO8</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">父类索引(<span style="font-family:'Comic Sans MS';">super_class</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> <span style="font-size:12px;"> <span style="font-size:12px;">父类索引,对于类来说,<span style="font-family:'Comic Sans MS';color:#FF6600;">super_class</span> 的值必须为 0 或者是对<span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool</span></span> 表中项目的一个有效索引值。如果它的值不为 0,那 <span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool</span></span> 表在这个索引处的项必须为<span style="font-family:'Microsoft YaHei';font-size:12px;"><span><span style="color:#FF6600;"><span style="font-family:'Comic Sans MS';">CONSTANT_Class_info</span></span></span></span> 类型常量,表示这个 <span style="font-family:'Comic Sans MS';">Class </span>文件所定义的类的直接父类。当前类的直接父类,以及它所有间接父类的<span style="font-family:'Comic Sans MS';color:#FF6600;">access_flag</span> 中都不能带有<span style="font-family:'Comic Sans MS';color:#FF6600;">ACC_FINAL</span> 标记。对于接口来说,它的<span style="font-family:'Comic Sans MS';">Class</span>文件的<span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';color:#FF6600;">super_class</span></span>项的值必须是对<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool</span></span></span>表中项目的一个有效索引值。<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool</span></span></span>表在这个索引处的项必须为代表<span style="font-family:'Comic Sans MS';"> java.lang.Object </span>的 <span style="font-family:'Microsoft YaHei';font-size:12px;"> <span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span><span style="color:#FF6600;"><span style="font-family:'Comic Sans MS';">CONSTANT_Class_info</span></span></span></span></span></span> 类型常量 。如果<span style="font-family:'Microsoft YaHei';"> <span style="font-family:'Comic Sans MS';"> Class </span></span>文件的 <span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';color:#FF6600;">super_class</span></span>的值为 0,那这个<span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';">Class</span></span>文件只可能是定义的是<span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';">java.lang.Object</span></span>类,只有它是唯一没有父类的类。</span></span></span><br></p> </fieldset><p><br></p> <p><br></p> <fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO9</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">接口计数器(<span style="font-family:'Comic Sans MS';">interfaces_count</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> </span><span style="font-family:'Microsoft YaHei';font-size:12px;">接口计数器,<span style="font-family:'Comic Sans MS';color:#FF6600;">interfaces_count</span>的值表示当前类或接口的直接父接口数量。</span><br></p> </fieldset><p><br></p> <br><fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO10</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">接口信息数据区(<span style="font-family:'Comic Sans MS';">interfaces[interfaces_count]</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> </span><span style="font-family:'Microsoft YaHei';font-size:12px;">接口表,<span style="font-family:'Comic Sans MS';color:#FF6600;">interfaces</span>[]数组中的每个成员的值必须是一个对<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">constant_pool</span></span></span></span></span></span>表中项目的一个有效索引值, 它的长度为 <span style="font-family:'Comic Sans MS';">interfaces_count</span>。每个成员 <span style="font-family:'Comic Sans MS';color:#FF6600;"> interfaces[i]</span> 必须为<span style="font-family:'Comic Sans MS';color:#FF6600;"> CONSTANT_Class_info</span>类型常量,其中<strong> 0 ≤ i <<span style="font-family:'Comic Sans MS';">interfaces_count</span></strong>。在<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">interfaces</span>[]</span>数组中,成员所表示的接口顺序和对应的源代码中给定的接口顺序(从左至右)一样,即<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">interfaces</span>[0]</span>对应的是源代码中最左边的接口。</span><br></p> </fieldset><p><br></p> <p><br></p> <fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO11</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">字段计数器(<span style="font-family:'Comic Sans MS';">fields_count</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> </span><span style="font-family:'Microsoft YaHei';font-size:12px;">字段计数器,<span style="font-family:'Comic Sans MS';color:#FF6600;">fields_count</span>的值表示当前 Class 文件<span style="font-family:'Comic Sans MS';color:#FF6600;"> fields[]</span>数组的成员个数。<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;"> fields[]</span></span>数组中每一项都是一个<span style="font-family:'Comic Sans MS';color:#FF6600;">field_info</span>结构的数据项,它用于表示该类或接口声明的类字段或者实例字段。</span><br></p> </fieldset><p><br></p> <fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO12</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">字段信息数据区(<span style="font-family:'Comic Sans MS';">fields[fields_count]</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> </span><span style="font-family:'Microsoft YaHei';font-size:12px;">字段表,<span style="font-family:'Comic Sans MS';color:#FF6600;">fields[]</span>数组中的每个成员都必须是一个<span style="font-family:'Comic Sans MS';color:#FF6600;">fields_info</span>结构的数据项,用于表示当前类或接口中某个字段的完整描述。<span style="font-family:'Comic Sans MS';color:#FF6600;"> fields[]</span>数组描述当前类或接口声明的所有字段,但不包括从父类或父接口继承的部分。</span><br></p> </fieldset><p><br></p> <br><fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO13</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">方法计数器(<span style="font-family:'Comic Sans MS';">methods_count</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> </span><span style="font-family:'Microsoft YaHei';font-size:12px;">方法计数器,<span style="font-family:'Comic Sans MS';color:#FF6600;"> methods_count</span>的值表示当前<span style="font-family:'Comic Sans MS';">Class</span> 文件<span style="font-family:'Comic Sans MS';color:#FF6600;"> methods[]</span>数组的成员个数。Methods[]数组中每一项都是一个 method_info 结构的数据项。</span><br></p> </fieldset><br><fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO14</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">方法信息数据区(<span style="font-family:'Comic Sans MS';">methods[methods_count]</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> </span><span style="font-family:'Microsoft YaHei';font-size:12px;">方法表,<span style="font-family:'Comic Sans MS';color:#FF6600;">methods[]</span> 数组中的每个成员都必须是一个<span style="font-family:'Comic Sans MS';color:#FF6600;"> method_info</span> 结构的数据项,用于表示当前类或接口中某个方法的完整描述。如果某个<span style="font-family:'Comic Sans MS';color:#FF6600;">method_info</span> 结构的<span style="font-family:'Comic Sans MS';color:#FF6600;">access_flags</span> 项既没有设置<span style="font-family:'Comic Sans MS';"> ACC_NATIVE</span> 标志也没有设置<span style="font-family:'Comic Sans MS';">ACC_ABSTRACT </span>标志,那么它所对应的方法体就应当可以被 Java 虚拟机直接从当前类加载,而不需要引用其它类。<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;"> method_info</span></span>结构可以表示类和接口中定义的所有方法,包括实例方法、类方法、实例初始化方法方法和类或接口初始化方法方法 。<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">methods[]</span></span>数组只描述当前类或接口中声明的方法,不包括从父类或父接口继承的方法。</span><br></p> </fieldset><p><br></p> <p><br></p> <fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO15</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">属性计数器(<span style="font-family:'Comic Sans MS';">attributes_count</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> </span><span style="font-family:'Microsoft YaHei';font-size:12px;"></span><span style="font-family:'Microsoft YaHei';font-size:12px;">属性计数器,<span style="font-family:'Comic Sans MS';color:#FF6600;">attributes_count</span>的值表示当前 Class 文件<span style="font-family:'Comic Sans MS';color:#FF6600;">attributes</span>表的成员个数。<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">attributes</span></span>表中每一项都是一个<span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_info</span> 结构的数据项。</span><br></p> </fieldset><br><fieldset><legend><span style="font-family:'Comic Sans MS';font-size:14px;">NO16</span><span style="font-size:14px;">.<span style="font-family:'Microsoft YaHei';">属性信息数据区(<span style="font-size:14px;"><span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';">attributes</span></span></span><span style="font-family:'Comic Sans MS';">[<span style="font-size:14px;"><span style="font-family:'Microsoft YaHei';"><span style="font-family:'Comic Sans MS';">attributes</span></span></span>_count]</span>)</span></span></legend> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> </span><span style="font-family:'Microsoft YaHei';font-size:12px;">属性表,<span style="font-family:'Comic Sans MS';color:#FF6600;">attributes</span> 表的每个项的值必须是<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">attribute_info</span></span>结构。</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="color:#FF6600;"> </span>在Java 7 规范里,<span style="font-family:'Comic Sans MS';">Class</span>文件结构中的<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">attributes</span></span>表的项包括下列定义的属性:<span style="font-family:'Comic Sans MS';color:#FF6600;"> InnerClasses 、 EnclosingMethod 、 Synthetic 、Signature、SourceFile,SourceDebugExtension 、Deprecated、RuntimeVisibleAnnotations 、RuntimeInvisibleAnnotations</span>以及<span style="font-family:'Comic Sans MS';color:#FF6600;">BootstrapMethods</span>属性。</span></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;"> 对于支持 <span style="font-family:'Microsoft YaHei';font-size:12px;"> <span style="font-family:'Comic Sans MS';">Class </span></span>文件格式版本号为 49.0 或更高的 Java 虚拟机实现,必须正确识别并读取<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">attributes</span></span>表中的<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">Signature</span></span>、<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">RuntimeVisibleAnnotations</span></span>和<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">RuntimeInvisibleAnnotations</span></span>属性。对于支持<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';">Class</span></span></span>文件格式版本号为 51.0 或更高的 Java 虚拟机实现,必须正确识别并读取 <span style="font-family:'Microsoft YaHei';font-size:12px;"> <span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">attributes</span></span></span>表中的<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">BootstrapMethods</span></span>属性。<span style="font-family:'Microsoft YaHei';font-size:12px;">Java 7 规范</span> 要求任一 Java 虚拟机实现可以自动忽略 Class 文件的 <span style="font-family:'Microsoft YaHei';font-size:12px;"> <span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';color:#FF6600;">attributes</span></span></span></span>表中的若干 (甚至全部) 它不可识别的属性项。任何本规范未定义的属性不能影响<span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Microsoft YaHei';font-size:12px;"><span style="font-family:'Comic Sans MS';">Class</span></span></span>文件的语义,只能提供附加的描述信息 。</span><br></p> </fieldset><p><br></p> <p><span style="font-family:'Microsoft YaHei';font-size:12px;">根据上述的叙述,我们可以将class的文件组织结构概括成以下面这个结构体:</span></p> <p><img srcwatermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHVhbmxvdWlz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""><br></p> <span style="font-size:10px;"> </div>