JVM---数据存储和访问(类文件结构)

一、类文件结构概述

计算机只识0和1
代码编译的结果从本地机器码到字节码是一个很重大意义的转变。

文件的数据项
在这里插入图片描述
把上面的文件数据项转化成图如下:
在这里插入图片描述
主次版本号
在这里插入图片描述
常量池:
包含两大类常量:字面量(Literal)和符号引用(Symbolic References)
字面量包括:文本字符串,声明为final的常量值等

符号引用(编译原理方面概念):
类和接口的全限定名(Fully Qualified Name)
字段的名称和描述符(Descriptor)
方法的名称和描述符

常量在存储的时候常量表
在这里插入图片描述

二、获取class文件示例一下

这里是在windows环境下打开CMD,到JDK安装目录下执行命令
使用javap -verbose Test(备注.class文件) 看不到所有内容

用法: javap <options> <classes>
其中, 可能的选项包括:
  -help  --help  -?        输出此用法消息
  -version                 版本信息
  -v  -verbose             输出附加信息
  -l                       输出行号和本地变量表
  -public                  仅显示公共类和成员
  -protected               显示受保护的/公共类和成员
  -package                 显示程序包/受保护的/公共类
                           和成员 (默认)
  -p  -private             显示所有类和成员
  -c                       对代码进行反汇编
  -s                       输出内部类型签名
  -sysinfo                 显示正在处理的类的
                           系统信息 (路径, 大小, 日期, MD5 散列)
  -constants               显示最终常量
  -classpath <path>        指定查找用户类文件的位置
  -cp <path>               指定查找用户类文件的位置
  -bootclasspath <path>    覆盖引导类文件的位置

在这里插入图片描述
改下命令输出到文件中
在这里插入图片描述
在这里插入图片描述
我们现在可以打开其中一个看下内容如下,想要看懂的话还需要参照常量池中的14种常量项的结构总表
常量池中的14种常量项的结构总表
在这里插入图片描述在这里插入图片描述

三、开始进入学习

先看下我们打开的demo文件整体结构图(常量池和内容信息也在字节码文件信息中由于特殊内容比较多,所以单独拉出来)
在这里插入图片描述
原始文件打开如下解析:

Classfile /D:/JD_SoftInstaller/RD_softInstaller/JDK/bin/Test.class
  Last modified 2019-1-18; size 2889 bytes
  MD5 checksum 6242eda79aea8128ea49a2dd0652454e
  Compiled from "Test.java"
public class test.Test
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
    #1 = Methodref          #46.#93       // java/lang/Object."<init>":()V
    #2 = Class              #94           // java/io/File
    #3 = String             #95           // C:\Users\XXXXXX\Desktop\dbData\goodsExtListUpdate.txt
    #4 = Methodref          #2.#96        // java/io/File."<init>":(Ljava/lang/String;)V
    #5 = Methodref          #2.#97        // java/io/File.createNewFile:()Z
    #6 = Class              #98           // java/io/BufferedWriter
    #7 = Class              #99           // java/io/FileWriter
    #8 = Methodref          #7.#100       // java/io/FileWriter."<init>":(Ljava/io/File;)V
    #9 = Methodref          #6.#101       // java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V
   #10 = Methodref          #45.#102      // test/Test.readAndWrite:(ILjava/io/BufferedWriter;)V
   #11 = Class              #103          // java/lang/Exception
   #12 = Methodref          #6.#104       // java/io/BufferedWriter.flush:()V
   #13 = Methodref          #6.#105       // java/io/BufferedWriter.close:()V
   #14 = String             #106          // C:\Users\XXXXXX\Desktop\dbData\goodsExtList.txt
   #15 = Class              #107          // java/io/InputStreamReader
   #16 = Class              #108          // java/io/FileInputStream
   #17 = Methodref          #16.#100      // java/io/FileInputStream."<init>":(Ljava/io/File;)V
   #18 = String             #109          // GBK
   #19 = Methodref          #15.#110      // java/io/InputStreamReader."<init>":(Ljava/io/InputStream;Ljava/lang/String;)V
   #20 = Class              #111          // java/io/BufferedReader
   #21 = Methodref          #20.#112      // java/io/BufferedReader."<init>":(Ljava/io/Reader;)V
   #22 = String             #113          //
   #23 = Methodref          #20.#114      // java/io/BufferedReader.readLine:()Ljava/lang/String;
   #24 = Class              #115          // java/lang/String
   #25 = Methodref          #24.#116      // java/lang/String.getBytes:(Ljava/lang/String;)[B
   #26 = Methodref          #24.#117      // java/lang/String."<init>":([BLjava/lang/String;)V
   #27 = String             #118          // hash
   #28 = Methodref          #24.#119      // java/lang/String.contains:(Ljava/lang/CharSequence;)Z
   #29 = String             #120          // CREATE TABLE `gold_pocket_goods_ext0` (
   #30 = Class              #121          // java/lang/StringBuilder
   #31 = Methodref          #30.#93       // java/lang/StringBuilder."<init>":()V
   #32 = Methodref          #30.#122      // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #33 = String             #123          // \n
   #34 = Methodref          #30.#124      // java/lang/StringBuilder.toString:()Ljava/lang/String;
   #35 = Methodref          #6.#125       // java/io/BufferedWriter.write:(Ljava/lang/String;)V
   #36 = String             #126          // set @sharding = 'gold_pocket_goods_ext
   #37 = Methodref          #30.#127      // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   #38 = String             #128          //  ID hash ' ;
   #39 = Fieldref           #129.#130     // java/lang/System.out:Ljava/io/PrintStream;
   #40 = Methodref          #131.#132     // java/io/PrintStream.println:(Ljava/lang/String;)V
   #41 = String             #133          // CREATE TABLE `gold_pocket_goods_ext
   #42 = String             #134          // ` (
   #43 = Class              #135          // java/lang/NullPointerException
   #44 = Methodref          #43.#93       // java/lang/NullPointerException."<init>":()V
   #45 = Class              #136          // test/Test
   #46 = Class              #137          // java/lang/Object
   #47 = Utf8               <init>
   #48 = Utf8               ()V
   #49 = Utf8               Code
   #50 = Utf8               LineNumberTable
   #51 = Utf8               LocalVariableTable
   #52 = Utf8               this
   #53 = Utf8               Ltest/Test;
   #54 = Utf8               main
   #55 = Utf8               ([Ljava/lang/String;)V
   #56 = Utf8               e
   #57 = Utf8               Ljava/lang/Exception;
   #58 = Utf8               args
   #59 = Utf8               [Ljava/lang/String;
   #60 = Utf8               writename
   #61 = Utf8               Ljava/io/File;
   #62 = Utf8               out
   #63 = Utf8               Ljava/io/BufferedWriter;
   #64 = Utf8               StackMapTable
   #65 = Class              #59           // "[Ljava/lang/String;"
   #66 = Class              #94           // java/io/File
   #67 = Class              #98           // java/io/BufferedWriter
   #68 = Class              #103          // java/lang/Exception
   #69 = Utf8               Exceptions
   #70 = Class              #138          // java/io/IOException
   #71 = Utf8               readAndWrite
   #72 = Utf8               (ILjava/io/BufferedWriter;)V
   #73 = Utf8               pathname
   #74 = Utf8               Ljava/lang/String;
   #75 = Utf8               filename
   #76 = Utf8               reader
   #77 = Utf8               Ljava/io/InputStreamReader;
   #78 = Utf8               br
   #79 = Utf8               Ljava/io/BufferedReader;
   #80 = Utf8               line
   #81 = Utf8               nullPoint
   #82 = Utf8               Ljava/lang/NullPointerException;
   #83 = Utf8               i
   #84 = Utf8               I
   #85 = Class              #115          // java/lang/String
   #86 = Class              #107          // java/io/InputStreamReader
   #87 = Class              #111          // java/io/BufferedReader
   #88 = Class              #135          // java/lang/NullPointerException
   #89 = Class              #139          // java/io/FileNotFoundException
   #90 = Class              #140          // java/io/UnsupportedEncodingException
   #91 = Utf8               SourceFile
   #92 = Utf8               Test.java
   #93 = NameAndType        #47:#48       // "<init>":()V
   #94 = Utf8               java/io/File
   #95 = Utf8               C:\Users\XXXXXX\Desktop\dbData\goodsExtListUpdate.txt
   #96 = NameAndType        #47:#141      // "<init>":(Ljava/lang/String;)V
   #97 = NameAndType        #142:#143     // createNewFile:()Z
   #98 = Utf8               java/io/BufferedWriter
   #99 = Utf8               java/io/FileWriter
  #100 = NameAndType        #47:#144      // "<init>":(Ljava/io/File;)V
  #101 = NameAndType        #47:#145      // "<init>":(Ljava/io/Writer;)V
  #102 = NameAndType        #71:#72       // readAndWrite:(ILjava/io/BufferedWriter;)V
  #103 = Utf8               java/lang/Exception
  #104 = NameAndType        #146:#48      // flush:()V
  #105 = NameAndType        #147:#48      // close:()V
  #106 = Utf8               C:\Users\XXXX\Desktop\dbData\goodsExtList.txt
  #107 = Utf8               java/io/InputStreamReader
  #108 = Utf8               java/io/FileInputStream
  #109 = Utf8               GBK
  #110 = NameAndType        #47:#148      // "<init>":(Ljava/io/InputStream;Ljava/lang/String;)V
  #111 = Utf8               java/io/BufferedReader
  #112 = NameAndType        #47:#149      // "<init>":(Ljava/io/Reader;)V
  #113 = Utf8
  #114 = NameAndType        #150:#151     // readLine:()Ljava/lang/String;
  #115 = Utf8               java/lang/String
  #116 = NameAndType        #152:#153     // getBytes:(Ljava/lang/String;)[B
  #117 = NameAndType        #47:#154      // "<init>":([BLjava/lang/String;)V
  #118 = Utf8               hash
  #119 = NameAndType        #155:#156     // contains:(Ljava/lang/CharSequence;)Z
  #120 = Utf8               CREATE TABLE `gold_pocket_goods_ext0` (
  #121 = Utf8               java/lang/StringBuilder
  #122 = NameAndType        #157:#158     // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #123 = Utf8               \n
  #124 = NameAndType        #159:#151     // toString:()Ljava/lang/String;
  #125 = NameAndType        #160:#141     // write:(Ljava/lang/String;)V
  #126 = Utf8               set @sharding = 'gold_pocket_goods_ext
  #127 = NameAndType        #157:#161     // append:(I)Ljava/lang/StringBuilder;
  #128 = Utf8                ID hash ' ;
  #129 = Class              #162          // java/lang/System
  #130 = NameAndType        #62:#163      // out:Ljava/io/PrintStream;
  #131 = Class              #164          // java/io/PrintStream
  #132 = NameAndType        #165:#141     // println:(Ljava/lang/String;)V
  #133 = Utf8               CREATE TABLE `gold_pocket_goods_ext
  #134 = Utf8               ` (
  #135 = Utf8               java/lang/NullPointerException
  #136 = Utf8               test/Test
  #137 = Utf8               java/lang/Object
  #138 = Utf8               java/io/IOException
  #139 = Utf8               java/io/FileNotFoundException
  #140 = Utf8               java/io/UnsupportedEncodingException
  #141 = Utf8               (Ljava/lang/String;)V
  #142 = Utf8               createNewFile
  #143 = Utf8               ()Z
  #144 = Utf8               (Ljava/io/File;)V
  #145 = Utf8               (Ljava/io/Writer;)V
  #146 = Utf8               flush
  #147 = Utf8               close
  #148 = Utf8               (Ljava/io/InputStream;Ljava/lang/String;)V
  #149 = Utf8               (Ljava/io/Reader;)V
  #150 = Utf8               readLine
  #151 = Utf8               ()Ljava/lang/String;
  #152 = Utf8               getBytes
  #153 = Utf8               (Ljava/lang/String;)[B
  #154 = Utf8               ([BLjava/lang/String;)V
  #155 = Utf8               contains
  #156 = Utf8               (Ljava/lang/CharSequence;)Z
  #157 = Utf8               append
  #158 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #159 = Utf8               toString
  #160 = Utf8               write
  #161 = Utf8               (I)Ljava/lang/StringBuilder;
  #162 = Utf8               java/lang/System
  #163 = Utf8               Ljava/io/PrintStream;
  #164 = Utf8               java/io/PrintStream
  #165 = Utf8               println
{
  public test.Test();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 9: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Ltest/Test;

  public static void main(java.lang.String[]) throws java.io.IOException;
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=5, locals=4, args_size=1
         0: new           #2                  // class java/io/File
         3: dup
         4: ldc           #3                  // String C:\Users\XXXXXXX\Desktop\dbData\goodsExtListUpdate.txt
         6: invokespecial #4                  // Method java/io/File."<init>":(Ljava/lang/String;)V
         9: astore_1
        10: aload_1
        11: invokevirtual #5                  // Method java/io/File.createNewFile:()Z
        14: pop
        15: new           #6                  // class java/io/BufferedWriter
        18: dup
        19: new           #7                  // class java/io/FileWriter
        22: dup
        23: aload_1
        24: invokespecial #8                  // Method java/io/FileWriter."<init>":(Ljava/io/File;)V
        27: invokespecial #9                  // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V
        30: astore_2
        31: iconst_0
        32: aload_2
        33: invokestatic  #10                 // Method readAndWrite:(ILjava/io/BufferedWriter;)V
        36: goto          48
        39: astore_3
        40: aload_2
        41: invokevirtual #12                 // Method java/io/BufferedWriter.flush:()V
        44: aload_2
        45: invokevirtual #13                 // Method java/io/BufferedWriter.close:()V
        48: return
      Exception table:
         from    to  target type
            31    36    39   Class java/lang/Exception
      LineNumberTable:
        line 15: 0
        line 16: 10
        line 17: 15
        line 20: 31
        line 25: 36
        line 22: 39
        line 23: 40
        line 24: 44
        line 26: 48
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           40       8     3     e   Ljava/lang/Exception;
            0      49     0  args   [Ljava/lang/String;
           10      39     1 writename   Ljava/io/File;
           31      18     2   out   Ljava/io/BufferedWriter;
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 39
          locals = [ class "[Ljava/lang/String;", class java/io/File, class java/io/BufferedWriter ]
          stack = [ class java/lang/Exception ]
        frame_type = 8 /* same */
    Exceptions:
      throws java.io.IOException

  public static void readAndWrite(int, java.io.BufferedWriter) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException, java.io.IOException;
    descriptor: (ILjava/io/BufferedWriter;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=5, locals=7, args_size=2
         0: ldc           #14                 // String C:\Users\XXXXX\Desktop\dbData\goodsExtList.txt
         2: astore_2
         3: new           #2                  // class java/io/File
         6: dup
         7: aload_2
         8: invokespecial #4                  // Method java/io/File."<init>":(Ljava/lang/String;)V
        11: astore_3
        12: new           #15                 // class java/io/InputStreamReader
        15: dup
        16: new           #16                 // class java/io/FileInputStream
        19: dup
        20: aload_3
        21: invokespecial #17                 // Method java/io/FileInputStream."<init>":(Ljava/io/File;)V
        24: ldc           #18                 // String GBK
        26: invokespecial #19                 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;Ljava/lang/String;)V
        29: astore        4
        31: new           #20                 // class java/io/BufferedReader
        34: dup
        35: aload         4
        37: invokespecial #21                 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V
        40: astore        5
        42: ldc           #22                 // String
        44: astore        6
        46: aload         5
        48: invokevirtual #23                 // Method java/io/BufferedReader.readLine:()Ljava/lang/String;
        51: astore        6
        53: aload         6
        55: ifnull        270
        58: new           #24                 // class java/lang/String
        61: dup
        62: aload         5
        64: invokevirtual #23                 // Method java/io/BufferedReader.readLine:()Ljava/lang/String;
        67: ldc           #18                 // String GBK
        69: invokevirtual #25                 // Method java/lang/String.getBytes:(Ljava/lang/String;)[B
        72: ldc           #18                 // String GBK
        74: invokespecial #26                 // Method java/lang/String."<init>":([BLjava/lang/String;)V
        77: astore        6
        79: aload         6
        81: ldc           #27                 // String hash
        83: invokevirtual #28                 // Method java/lang/String.contains:(Ljava/lang/CharSequence;)Z
        86: ifne          123
        89: aload         6
        91: ldc           #29                 // String CREATE TABLE `gold_pocket_goods_ext0` (
        93: invokevirtual #28                 // Method java/lang/String.contains:(Ljava/lang/CharSequence;)Z
        96: ifne          123
        99: aload_1
       100: new           #30                 // class java/lang/StringBuilder
       103: dup
       104: invokespecial #31                 // Method java/lang/StringBuilder."<init>":()V
       107: aload         6
       109: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       112: ldc           #33                 // String \n
       114: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       117: invokevirtual #34                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       120: invokevirtual #35                 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V
       123: aload         6
       125: ldc           #27                 // String hash
       127: invokevirtual #28                 // Method java/lang/String.contains:(Ljava/lang/CharSequence;)Z
       130: ifeq          195
       133: iload_0
       134: ifeq          163
       137: new           #30                 // class java/lang/StringBuilder
       140: dup
       141: invokespecial #31                 // Method java/lang/StringBuilder."<init>":()V
       144: ldc           #36                 // String set @sharding = 'gold_pocket_goods_ext
       146: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       149: iload_0
       150: invokevirtual #37                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
       153: ldc           #38                 // String  ID hash ' ;
       155: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       158: invokevirtual #34                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       161: astore        6
       163: getstatic     #39                 // Field java/lang/System.out:Ljava/io/PrintStream;
       166: aload         6
       168: invokevirtual #40                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       171: aload_1
       172: new           #30                 // class java/lang/StringBuilder
       175: dup
       176: invokespecial #31                 // Method java/lang/StringBuilder."<init>":()V
       179: aload         6
       181: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       184: ldc           #33                 // String \n
       186: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       189: invokevirtual #34                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       192: invokevirtual #35                 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V
       195: aload         6
       197: ldc           #29                 // String CREATE TABLE `gold_pocket_goods_ext0` (
       199: invokevirtual #28                 // Method java/lang/String.contains:(Ljava/lang/CharSequence;)Z
       202: ifeq          53
       205: iload_0
       206: ifeq          235
       209: new           #30                 // class java/lang/StringBuilder
       212: dup
       213: invokespecial #31                 // Method java/lang/StringBuilder."<init>":()V
       216: ldc           #41                 // String CREATE TABLE `gold_pocket_goods_ext
       218: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       221: iload_0
       222: invokevirtual #37                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
       225: ldc           #42                 // String ` (
       227: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       230: invokevirtual #34                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       233: astore        6
       235: getstatic     #39                 // Field java/lang/System.out:Ljava/io/PrintStream;
       238: aload         6
       240: invokevirtual #40                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       243: aload_1
       244: new           #30                 // class java/lang/StringBuilder
       247: dup
       248: invokespecial #31                 // Method java/lang/StringBuilder."<init>":()V
       251: aload         6
       253: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       256: ldc           #33                 // String \n
       258: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       261: invokevirtual #34                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       264: invokevirtual #35                 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V
       267: goto          53
       270: goto          300
       273: astore_2
       274: iinc          0, 1
       277: iload_0
       278: sipush        512
       281: if_icmpge     292
       284: iload_0
       285: aload_1
       286: invokestatic  #10                 // Method readAndWrite:(ILjava/io/BufferedWriter;)V
       289: goto          300
       292: new           #43                 // class java/lang/NullPointerException
       295: dup
       296: invokespecial #44                 // Method java/lang/NullPointerException."<init>":()V
       299: athrow
       300: return
      Exception table:
         from    to  target type
             0   270   273   Class java/lang/NullPointerException
      LineNumberTable:
        line 30: 0
        line 31: 3
        line 32: 12
        line 34: 31
        line 36: 42
        line 37: 46
        line 38: 53
        line 40: 58
        line 41: 79
        line 42: 99
        line 45: 123
        line 46: 133
        line 47: 137
        line 49: 163
        line 50: 171
        line 52: 195
        line 53: 205
        line 54: 209
        line 56: 235
        line 57: 243
        line 69: 270
        line 62: 273
        line 63: 274
        line 64: 277
        line 65: 284
        line 67: 292
        line 71: 300
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            3     267     2 pathname   Ljava/lang/String;
           12     258     3 filename   Ljava/io/File;
           31     239     4 reader   Ljava/io/InputStreamReader;
           42     228     5    br   Ljava/io/BufferedReader;
           46     224     6  line   Ljava/lang/String;
          274      26     2 nullPoint   Ljava/lang/NullPointerException;
            0     301     0     i   I
            0     301     1   out   Ljava/io/BufferedWriter;
      StackMapTable: number_of_entries = 9
        frame_type = 255 /* full_frame */
          offset_delta = 53
          locals = [ int, class java/io/BufferedWriter, class java/lang/String, class java/io/File, class java/io/InputStreamReader, class java/io/BufferedReader, class java/lang/String ]
          stack = []
        frame_type = 251 /* same_frame_extended */
          offset_delta = 69
        frame_type = 39 /* same */
        frame_type = 31 /* same */
        frame_type = 39 /* same */
        frame_type = 255 /* full_frame */
          offset_delta = 34
          locals = [ int, class java/io/BufferedWriter ]
          stack = []
        frame_type = 66 /* same_locals_1_stack_item */
          stack = [ class java/lang/NullPointerException ]
        frame_type = 252 /* append */
          offset_delta = 18
          locals = [ class java/lang/NullPointerException ]
        frame_type = 250 /* chop */
          offset_delta = 7
    Exceptions:
      throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException, java.io.IOException
}
SourceFile: "Test.java"

四、解析内容讲解

1、字节码文件信息
开头的7行信息包括:Class文件当前所在位置,最后修改时间,文件大小,MD5值,编译自哪个文件,类的全限定名,jdk次版本号,主版本号。 然后紧接着的是该类的访问标志:ACC_PUBLIC, ACC_SUPER,访问标志的含义如下:
在这里插入图片描述
2、常量池信息
截取部分内容对比原代码红色框内容
在常量池中,该段代码分布情况。

Constant pool:
    #1 = Methodref          #46.#93       // java/lang/Object."<init>":()V
    #2 = Class              #94           // java/io/File
    #3 = String             #95           // C:\Users\XXXXXX\Desktop\dbData\goodsExtListUpdate.txt

在这里插入图片描述
第一个常量是一个方法定义,指向了第46和第93个常量。以此类推查看第46和第93个常量。
在这里插入图片描述
在这里插入图片描述
最后可以拼接成第一个常量右侧的注释内容:

java/lang/Object."<init>":()V

这段可以理解为该类的实例构造器的声明,由于Main类没有重写构造方法,所以调用的是父类的构造方法。此处也说明了Main类的直接父类是Object。 该方法默认返回值是V, 也就是void,无返回值。
对于后面的V
在这里插入图片描述
对于数组类型,每一位使用一个前置的"[“字符来描述,如定义一个java.lang.String[][]类型的维数组,将被记录为”[[Ljava/lang/String;"


3、内容的拆分先提下字段的含义:
在这里插入图片描述
对于类的字段access_flags标识有如下几个含义
在这里插入图片描述
对于方法access_flags标识有如下几个含义
在这里插入图片描述
属性预定义的标识有如下定义:
在这里插入图片描述
在这里插入图片描述
4、对于本文demo中属性结构如下:

descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:

      Exception table:

      LineNumberTable:

      LocalVariableTable:
     
      StackMapTable: number_of_entries = 2
     
    Exceptions:

5、那么code的内容结构是什么样的?
在这里插入图片描述

这里重点说明一点code_length,同事一个u4类型的长度值,理论上最大值可以达到2^32-1,但是虚拟机中限制了一个方法长度不允许超过65535条字节码指令。如果不是刻意的话,或者复杂的Jsp文件的话,那么应该不会导致编译失败。

LineNumberTable
该属性的作用是描述源码行号与字节码行号(字节码偏移量)之间的对应关系。可以使用 -g:none 或-g:lines选项来取消或要求生成这项信息,如果选择不生成LineNumberTable,当程序运行异常时将无法获取到发生异常的源码行号,也无法按照源码的行数来调试程序。


LocalVariableTable
该属性的作用是描述帧栈中局部变量与源码中定义的变量之间的关系。可以使用 -g:none 或 -g:vars来取消或生成这项信息,如果没有生成这项信息,那么当别人引用这个方法时,将无法获取到参数名称,取而代之的是arg0, arg1这样的占位符。
在这里需要引入的另外一个LocalVariableTypeTable。仅仅是把记录的字段描述符的descriptior_index替换成了字段的特征签名
(Signature)由于描述附中泛型的参数化类型被擦除掉,描述符就不能准确描述泛型类型了,所以才需要这个变量属性LocalVariableTypeTable。对于非泛型类型来说,描述符合特征签名描述的信息基本一致。

5.1异常表的属性结构:
在这里插入图片描述
引入深入理解Java虚拟机中的案例如下
在这里插入图片描述
在这里插入图片描述
我们这里的代码demo示例如下

public static void main(java.lang.String[]) throws java.io.IOException;
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=5, locals=4, args_size=1
         0: new           #2                  // class java/io/File
         3: dup
         4: ldc           #3                  // String C:\Users\liuxiaocheng\Desktop\dbData\goodsExtListUpdate.txt
         6: invokespecial #4                  // Method java/io/File."<init>":(Ljava/lang/String;)V
         9: astore_1
        10: aload_1
        11: invokevirtual #5                  // Method java/io/File.createNewFile:()Z
        14: pop
        15: new           #6                  // class java/io/BufferedWriter
        18: dup
        19: new           #7                  // class java/io/FileWriter
        22: dup
        23: aload_1
        24: invokespecial #8                  // Method java/io/FileWriter."<init>":(Ljava/io/File;)V
        27: invokespecial #9                  // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V
        30: astore_2
        31: iconst_0
        32: aload_2
        33: invokestatic  #10                 // Method readAndWrite:(ILjava/io/BufferedWriter;)V
        36: goto          48
        39: astore_3
        40: aload_2
        41: invokevirtual #12                 // Method java/io/BufferedWriter.flush:()V
        44: aload_2
        45: invokevirtual #13                 // Method java/io/BufferedWriter.close:()V
        48: return
      Exception table:
         from    to  target type
            31    36    39   Class java/lang/Exception
      LineNumberTable:
        line 15: 0
        line 16: 10
        line 17: 15
        line 20: 31
        line 25: 36
        line 22: 39
        line 23: 40
        line 24: 44
        line 26: 48
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           40       8     3     e   Ljava/lang/Exception;
            0      49     0  args   [Ljava/lang/String;
           10      39     1 writename   Ljava/io/File;
           31      18     2   out   Ljava/io/BufferedWriter;
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 39
          locals = [ class "[Ljava/lang/String;", class java/io/File, class java/io/BufferedWriter ]
          stack = [ class java/lang/Exception ]
        frame_type = 8 /* same */
    Exceptions:
      throws java.io.IOException
stack
最大操作数栈,JVM运行时会根据这个值来分配栈帧(Frame)中的操作栈深度,此处为1


locals:
局部变量所需的存储空间,单位为Slot, Slot是虚拟机为局部变量分配内存时所使用的最小单位,为4个字节大小。方法参数(包括实例方法中的隐藏参数this),显示异常处理器的参数(try catch中的catch块所定义的异常),方法体中定义的局部变量都需要使用局部变量表来存放。值得一提的是,locals的大小并不一定等于所有局部变量所占的Slot之和,因为局部变量中的Slot是可以重用的。


args_size:
方法参数的个数,这里是1,因为每个实例方法都会有一个隐藏参数this,如果方法声明为static 那么这里就会显示为0
start 表示该局部变量在哪一行开始可见,length表示可见行数,Slot(虚拟机为局部变量分配内存所使用的最小单位,对于byte,char,float,int ,short,boolean,和returnAddress等长度不超过32位的数据类型,每个局部变量占用1个Slot,而double和long这两种64位的数据类型则需要两个Slot来存放),Name是变量名称,然后是类型签名。
StackMapTable:
这个属性在虚拟机类加载的字节码验证阶段被新类型检查验证器(Type Checker)使用,目的在于代替以前比较消耗性能的基于数据流分析的类型推导验证器。一个方法的code属性最多只能有一个StackMapTable属性,否则抛出ClassFormatError异常。
 Exception table:
 异常表实际上是Java代码的一部分,编译器使用异常表而不是简单的跳转命令来实现Java异常及finally处理机制
 Exceptions:与异常表不一样,这里是在方法throws抛出的时候列举的异常
 Signature:
在任何类,接口,初始化方法或成员的泛型签名如果包含了类型变量(Type Variables)或参数化类型(Parameterized Types),则Signature属性为他记录泛型签名信息,之所以专门使用这样的一个属性去记录泛型类型,是因为Java语言的泛型采用的是擦除法实现的伪泛型。

Signature结构如下:
在这里插入图片描述
signature_index项的值必须是一个对常量池的有效索引。常量池在该索引处的项必须是CONSTANT_Utf8_info结构,标识类签名,表示类签名、方法类型签名或字段类型签名。

StackMapTable结构如下:
在这里插入图片描述

SourceFile: "Test.java"
用于记录生成这个Class文件的源码文件名称,可选。
可以使用 -g:none 或-g:sources选项来取消或要求生成这项信息,

在这里插入图片描述
我们这里没有提到的还有常量和内部类属性
常量ConstantValue属性结构

在这里插入图片描述
InnerClasses内部类属性结构
在这里插入图片描述

number_of_classes
在这里插入图片描述
inner_class_access_flags
在这里插入图片描述
Deprecated和Synthetic属性
在这里插入图片描述
BootstrapMethods属性

在这里插入图片描述
bootstrap_method
在这里插入图片描述
bootstrap_methods[]数组中每个成员都需要包含的内容如下
在这里插入图片描述