Class类文件的结构
这个很适合用access_flags标志来表示,跟随access_flags标志的是两项索引值:name_index和descriptor index.它们都是对常?最池的引用,分别代表着字段的简单名称以及字段和方法的描述符。现在需要解释一下“简?单名称”、“描述符”以及前面出现过多次的“全限定名”这三种特殊字符串的概念。
其余的方法区和属性区都是差不多的方法。
public class JavaTest { private static String name = "JVM"; public static void main(String[] args) { System.out.println("Hello " + name); } }
出来的头文件是这样的
每个class文件的头4个字节称为魔数,用于确定这个文件是否能被虚拟机所接受。class文件的魔数值为CAFEBABE。
第5、6字节为次版本号,7、8字节为主版本号。Java的主版本号从45开始,JDK1.1之后每个大版本发布,主版本号加1。高版本的jdk能前向兼容之前版本的class文件,但不能运行以后版本的class文件。
从图1可以看到,次版本号为0000,主版本号为0031,这说明该class文件可以被1.5及以后版本的jdk运行。
这个代表了常量池中的数量,34=>52-1 = 51个
例如第一个是0A,那么对应就是10,表中为类方法的符号引用,下面一个是000C=>12.......
bogon:Downloads shiyangsheng$ javap -v JavaTest.class Classfile /Users/shiyangsheng/Downloads/JavaTest.class Last modified 2018-3-17; size 842 bytes MD5 checksum fbb2370c6b7413a0636806a0e492224a Compiled from "JavaTest.java" public class com.youzan.shys.advice.JavaTest minor version: 0 major version: 49 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #12.#29 // java/lang/Object."<init>":()V #2 = Fieldref #30.#31 // java/lang/System.out:Ljava/io/PrintStream; #3 = Class #32 // java/lang/StringBuilder #4 = Methodref #3.#29 // java/lang/StringBuilder."<init>":()V #5 = String #33 // Hello #6 = Methodref #3.#34 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #7 = Fieldref #11.#35 // com/youzan/shys/advice/JavaTest.name:Ljava/lang/String; #8 = Methodref #3.#36 // java/lang/StringBuilder.toString:()Ljava/lang/String; #9 = Methodref #37.#38 // java/io/PrintStream.println:(Ljava/lang/String;)V #10 = String #39 // JVM #11 = Class #40 // com/youzan/shys/advice/JavaTest #12 = Class #41 // java/lang/Object #13 = Utf8 name #14 = Utf8 Ljava/lang/String; #15 = Utf8 <init> #16 = Utf8 ()V #17 = Utf8 Code #18 = Utf8 LineNumberTable #19 = Utf8 LocalVariableTable #20 = Utf8 this #21 = Utf8 Lcom/youzan/shys/advice/JavaTest; #22 = Utf8 main #23 = Utf8 ([Ljava/lang/String;)V #24 = Utf8 args #25 = Utf8 [Ljava/lang/String; #26 = Utf8 <clinit> #27 = Utf8 SourceFile #28 = Utf8 JavaTest.java #29 = NameAndType #15:#16 // "<init>":()V #30 = Class #42 // java/lang/System #31 = NameAndType #43:#44 // out:Ljava/io/PrintStream; #32 = Utf8 java/lang/StringBuilder #33 = Utf8 Hello #34 = NameAndType #45:#46 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #35 = NameAndType #13:#14 // name:Ljava/lang/String; #36 = NameAndType #47:#48 // toString:()Ljava/lang/String; #37 = Class #49 // java/io/PrintStream #38 = NameAndType #50:#51 // println:(Ljava/lang/String;)V #39 = Utf8 JVM #40 = Utf8 com/youzan/shys/advice/JavaTest #41 = Utf8 java/lang/Object #42 = Utf8 java/lang/System #43 = Utf8 out #44 = Utf8 Ljava/io/PrintStream; #45 = Utf8 append #46 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #47 = Utf8 toString #48 = Utf8 ()Ljava/lang/String; #49 = Utf8 java/io/PrintStream #50 = Utf8 println #51 = Utf8 (Ljava/lang/String;)V
紧接着常量池之后的两个字节表示访问标志,主要是用来标记类或者接口层次的一些属性。目标之定义了16个标志位中的8位,没有使用到的一律为0。 具体标志位如下表:
在访问标志之后,有3个用来确定一个类的继承关系的数据,按先后顺序分别是:
原文:https://www.cnblogs.com/SmartCat994/p/13197817.html