class 文件的常量池解析

定义:

  • 字面量和引用:就是class文件中,所有符号值(这要从编译原理角度去解释),并不是纯粹的字段变量值。

    • 例如:private final int a = 10; (常量:变量名a, integer:10)

      • #28 = NameAndType #10:#11
      • #10 = Utf8 a
      • #11 = Utf8 I
    • 编译原理中的符号,在文件运行阶段用于存在符号及可能被外部引用的符号

      • 类和接口的全限定名 (Fully Qualified Name)
      • 字段的名称和描述符 (Descriptor)
      • 方法的名称和描述符
      • final 标记的字段值

查看命令

javap:反编译查看.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>    覆盖引导类文件的位置

案例

.java文件
package com.fxl.fight2.service;

public class ClassTest {

	private final int a = 11;
	private int b = 11;
	private int c = 10;
	private UserDto u1 = new UserDto();
}


javap -v 反编译文件
Classfile /C:/Users/ssHss/Desktop/JVM/class/ClassTest.class
  Last modified 2018-3-3; size 541 bytes
  MD5 checksum ba4f2da1b37c1def6459f2639e6a8a7f
  Compiled from "ClassTest.java"
public class com.fxl.fight2.service.ClassTest
  minor version: 0  "次版本号"
  major version: 51 "主版本号"
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:  "常量池"
   "index" = "类型"        "值(数据值,index大小)"   "注解"
   #1 = Methodref          #9.#27         // java/lang/Object."<init>":()V
   #2 = Fieldref           #8.#28         // com/fxl/fight2/service/ClassTest.a:I
   #3 = Fieldref           #8.#29         // com/fxl/fight2/service/ClassTest.b:I
   #4 = Fieldref           #8.#30         // com/fxl/fight2/service/ClassTest.c:I
   #5 = Class              #31            // com/fxl/fight2/service/UserDto
   #6 = Methodref          #5.#27         // com/fxl/fight2/service/UserDto."<init>":()V
   #7 = Fieldref           #8.#32         // com/fxl/fight2/service/ClassTest.u1:Lcom/fxl/fight2/service/UserDto;
   #8 = Class              #33            // com/fxl/fight2/service/ClassTest
   #9 = Class              #34            // java/lang/Object
  #10 = Utf8               a
  #11 = Utf8               I
  #12 = Utf8               ConstantValue
  #13 = Integer            11
  #14 = Utf8               b
  #15 = Utf8               c
  #16 = Utf8               u1
  #17 = Utf8               Lcom/fxl/fight2/service/UserDto;

  #18 = Utf8               <init>   ".class文件初始化需要的字符"
  #19 = Utf8               ()V      ".class文件初始化需要的字符"
  
  #20 = Utf8               Code
  #21 = Utf8               LineNumberTable
  #22 = Utf8               LocalVariableTable
  #23 = Utf8               this
  #24 = Utf8               Lcom/fxl/fight2/service/ClassTest;
  #25 = Utf8               SourceFile
  #26 = Utf8               ClassTest.java
  
  #27 = NameAndType        #18:#19        // "<init>":()V "初始"
  #28 = NameAndType        #10:#11        // a:I
  #29 = NameAndType        #14:#11        // b:I
  #30 = NameAndType        #15:#11        // c:I
  
  #31 = Utf8               com/fxl/fight2/service/UserDto   "index=31:存放字符串内容:com/fxl/fight2/service/UserDto"
  #32 = NameAndType        #16:#17        // u1:Lcom/fxl/fight2/service/UserDto;
  #33 = Utf8               com/fxl/fight2/service/ClassTest "index=33:存放字符串内容:com/fxl/fight2/service/ClassTest"
  #34 = Utf8               java/lang/Object "index=34:存放字符串内容:com/fxl/fight2/service/Object"
  "指令"
{
  public com.fxl.fight2.service.ClassTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         
         4: aload_0
         5: bipush        11    "被final修饰,直接用11表示"
         7: putfield      #2                  // Field a:I
         
        10: aload_0
        11: bipush        11        "没有被final修饰,但是被static修饰,直接用11表示"
        13: putfield      #3                  // Field b:I
        
        16: aload_0
        17: bipush        10    "没有被修饰,直接用11表示"
        19: putfield      #4                  // Field c:I
        
        22: aload_0
        23: new           #5                  // class com/fxl/fight2/service/UserDto
        26: dup
        27: invokespecial #6                  // Method com/fxl/fight2/service/UserDto."<init>":()V
        30: putfield      #7                  // Field u1:Lcom/fxl/fight2/service/UserDto;
        
        33: return
        
      LineNumberTable:
        line 3: 0
        line 5: 4
        line 6: 10
        line 7: 16
        line 8: 22
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      34     0  this   Lcom/fxl/fight2/service/ClassTest;
}
SourceFile: "ClassTest.java"

猜你喜欢

转载自my.oschina.net/u/2246410/blog/1800659