常量池

源地址:http://bbs.csdn.net/topics/390292076

下面这段内容是我扒的一个回帖大侠的:

什么是常量池?
每个类都有自己的常量池。常量池类似于数组,通过索引来访问。

常量池放了什么东西?

放了方法名、方法描述符、类名、字段名,字段描述符,常量String的utf-8编码形式,常量int,常量float,常量double等
如:anewarray       #14; //class java/net/URL
这条指令表示创建一个常量池中索引为14的项所表示的类的数组,javap指令在反编译的时候将索引为14的项的内容注释了下,表示一个类:java.net.URL
又如:invokestatic    #18; //Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
常量池索引为18的项表示一个方法,是Thread类的currentThread方法,返回值是java.lang.Thread
再如:ldc     #22; //String main
从常量池索引为22的项中取值入栈。索引为22的常量池是什么内容?一个String,字面值为"main"


诸如此类,想反编译一个类(如Test),使用:javap -c Test
想查看类中常量池的内容,使用:javap -verbose -c Test

以下是我的一个类中的常量池的内容:

 Constant pool:
const #1 = Method       #32.#47;        //  java/lang/Object."<init>":()V
const #2 = Method       #48.#49;        //  java/lang/Runtime.getRuntime:()Ljava/lang/Runtime;
const #3 = class        #50;    //  ClassLoaderTest$1
const #4 = Method       #3.#47; //  ClassLoaderTest$1."<init>":()V
const #5 = Method       #48.#53;        //  java/lang/Runtime.addShutdownHook (Ljava/lang/Thread;)V
const #6 = class        #54;    //  java/util/ArrayList
const #7 = Method       #6.#47; //  java/util/ArrayList."<init>":()V
const #8 = class        #55;    //  java/io/File
const #9 = String       #56;    //  E:\helloworld.jar/
const #10 = Method      #8.#57; //  java/io/File."<init>":(Ljava/lang/String;)V
const #11 = Method      #8.#58; //  java/io/File.toURL:()Ljava/net/URL;
const #12 = Method      #6.#59; //  java/util/ArrayList.add:(Ljava/lang/Object;)Z
const #13 = class       #60;    //  java/net/URLClassLoader
const #14 = class       #61;    //  java/net/URL
const #15 = Method      #6.#62; //  java/util/ArrayList.toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
const #16 = class       #63;    //  "[Ljava/net/URL;"
const #17 = Method      #13.#64;        //  java/net/URLClassLoader."<init>":([Ljava/net/URL;)V
const #18 = Method      #65.#66;        //  java/lang/Thread.currentThread:()Ljava/lang/Thread;
const #19 = Method      #65.#67;        //  java/lang/Thread.setContextClassLoader:(Ljava/lang/ClassLoade
const #20 = String      #68;    //  test.Hello
const #21 = Method      #23.#69;        //  java/lang/Class.forName:(Ljava/lang/String;ZLjava/lang/ClassL
const #22 = String      #41;    //  main
const #23 = class       #70;    //  java/lang/Class
const #24 = class       #71;    //  java/lang/String
const #25 = Method      #72.#73;        //  java/lang/reflect/Array.newInstance:(Ljava/lang/Class;I)Ljava
const #26 = Method      #32.#74;        //  java/lang/Object.getClass:()Ljava/lang/Class;
const #27 = Method      #23.#75;        //  java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Clas
const #28 = Method      #76.#77;        //  java/util/Arrays.asList:([Ljava/lang/Object;)Ljava/util/List;
const #29 = InterfaceMethod     #78.#79;        //  java/util/List.subList:(II)Ljava/util/List;
const #30 = InterfaceMethod     #78.#62;        //  java/util/List.toArray:([Ljava/lang/Object;)[Ljava/la
const #31 = class       #80;    //  "[Ljava/lang/String;"
const #32 = class       #81;    //  java/lang/Object
const #33 = Method      #82.#83;        //  java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lan
const #34 = class       #84;    //  java/lang/reflect/InvocationTargetException
const #35 = Method      #34.#85;        //  java/lang/reflect/InvocationTargetException.getTargetExceptio
const #36 = class       #86;    //  ClassLoaderTest
const #37 = Asciz       <init>;
const #38 = Asciz       ()V;
const #39 = Asciz       Code;
const #40 = Asciz       LineNumberTable;
const #41 = Asciz       main;
const #42 = Asciz       ([Ljava/lang/String;)V;
const #43 = Asciz       Exceptions;
const #44 = class       #87;    //  java/lang/Throwable
const #45 = Asciz       SourceFile;
const #46 = Asciz       ClassLoaderTest.java;
const #47 = NameAndType #37:#38;//  "<init>":()V
const #48 = class       #88;    //  java/lang/Runtime
const #49 = NameAndType #89:#90;//  getRuntime:()Ljava/lang/Runtime;
const #50 = Asciz       ClassLoaderTest$1;
const #51 = Asciz       ;
const #52 = Asciz       InnerClasses;
const #53 = NameAndType #91:#92;//  addShutdownHook:(Ljava/lang/Thread;)V
const #54 = Asciz       java/util/ArrayList;
const #55 = Asciz       java/io/File;
const #56 = Asciz       E:\helloworld.jar/;
const #57 = NameAndType #37:#93;//  "<init>":(Ljava/lang/String;)V
const #58 = NameAndType #94:#95;//  toURL:()Ljava/net/URL;
const #59 = NameAndType #96:#97;//  add:(Ljava/lang/Object;)Z
const #60 = Asciz       java/net/URLClassLoader;
const #61 = Asciz       java/net/URL;
const #62 = NameAndType #98:#99;//  toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
const #63 = Asciz       [Ljava/net/URL;;
const #64 = NameAndType #37:#100;//  "<init>":([Ljava/net/URL;)V
const #65 = class       #101;   //  java/lang/Thread
const #66 = NameAndType #102:#103;//  currentThread:()Ljava/lang/Thread;
const #67 = NameAndType #104:#105;//  setContextClassLoader:(Ljava/lang/ClassLoader;)V
const #68 = Asciz       test.Hello;
const #69 = NameAndType #106:#107;//  forName:(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Clas
const #70 = Asciz       java/lang/Class;
const #71 = Asciz       java/lang/String;
const #72 = class       #108;   //  java/lang/reflect/Array
const #73 = NameAndType #109:#110;//  newInstance:(Ljava/lang/Class;I)Ljava/lang/Object;
const #74 = NameAndType #111:#112;//  getClass:()Ljava/lang/Class;
const #75 = NameAndType #113:#114;//  getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/
const #76 = class       #115;   //  java/util/Arrays
const #77 = NameAndType #116:#117;//  asList:([Ljava/lang/Object;)Ljava/util/List;
const #78 = class       #118;   //  java/util/List
const #79 = NameAndType #119:#120;//  subList:(II)Ljava/util/List;
const #80 = Asciz       [Ljava/lang/String;;
const #81 = Asciz       java/lang/Object;
const #82 = class       #121;   //  java/lang/reflect/Method
const #83 = NameAndType #122:#123;//  invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
const #84 = Asciz       java/lang/reflect/InvocationTargetException;
const #85 = NameAndType #124:#125;//  getTargetException:()Ljava/lang/Throwable;
const #86 = Asciz       ClassLoaderTest;
const #87 = Asciz       java/lang/Throwable;
const #88 = Asciz       java/lang/Runtime;
const #89 = Asciz       getRuntime;
const #90 = Asciz       ()Ljava/lang/Runtime;;
const #91 = Asciz       addShutdownHook;
const #92 = Asciz       (Ljava/lang/Thread;)V;
const #93 = Asciz       (Ljava/lang/String;)V;
const #94 = Asciz       toURL;
const #95 = Asciz       ()Ljava/net/URL;;
const #96 = Asciz       add;
const #97 = Asciz       (Ljava/lang/Object;)Z;
const #98 = Asciz       toArray;
const #99 = Asciz       ([Ljava/lang/Object;)[Ljava/lang/Object;;
const #100 = Asciz      ([Ljava/net/URL;)V;
const #101 = Asciz      java/lang/Thread;
const #102 = Asciz      currentThread;
const #103 = Asciz      ()Ljava/lang/Thread;;
const #104 = Asciz      setContextClassLoader;
const #105 = Asciz      (Ljava/lang/ClassLoader;)V;
const #106 = Asciz      forName;
const #107 = Asciz      (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;;
const #108 = Asciz      java/lang/reflect/Array;
const #109 = Asciz      newInstance;
const #110 = Asciz      (Ljava/lang/Class;I)Ljava/lang/Object;;
const #111 = Asciz      getClass;
const #112 = Asciz      ()Ljava/lang/Class;;
const #113 = Asciz      getMethod;
const #114 = Asciz      (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;;
const #115 = Asciz      java/util/Arrays;
const #116 = Asciz      asList;
const #117 = Asciz      ([Ljava/lang/Object;)Ljava/util/List;;
const #118 = Asciz      java/util/List;
const #119 = Asciz      subList;
const #120 = Asciz      (II)Ljava/util/List;;
const #121 = Asciz      java/lang/reflect/Method;
const #122 = Asciz      invoke;
const #123 = Asciz      (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;;
const #124 = Asciz      getTargetException;
const #125 = Asciz      ()Ljava/lang/Throwable;;

javap给它的注释很明了
const #1 = Method       #32.#47;        //  java/lang/Object."<init>":()V
常量池索引为1的项,表示的是一个方法,具体的方法是Object的<init>

常量池中放入的诸如方法信息字段信息类等信息,在运行的时候,jvm需要将这些符号引用替换成直接引用,如表示字段的常量池项可能是一个本地指针,指向方法区类元数据中的字段,再如表示方法的项,可能是指向方法表的一个指针;还有一些常量池存储的并不是符号引用,如CONSTANT_DOUBLE_INFO,存的就是double值本身,在jvm装载类的解析过程中并不需要对这样的常量池项做什么操作。


jvm实例中维护了一张表,就叫它intern列表吧,专门用来存储具有某种特征的字符串的。
例如解析字符串时,在解析CONSTANT_String_info时,如果在intern列表没有发现CONSTANT_String_info所表示的字符串对象,就创建一个,并把它的引用加入intern列表中,同时将CONSTANT_String_info也指向这个对象;如果intern列表中已经存在CONSTANT_String_info所表示的String对象,就直接将CONSTANT_String_info指向这个对象

另外,调用String的intern()方法,若在intern列表中没有该String对象所表示的字符序列,也就将一个对象加入这个intern列表,但是加入的是新创建一个相同的字符串对象还是将该字符换本身加进去,不同的jvm做法不同,见:http://www.iteye.com/topic/1112592

转载于:https://my.oschina.net/u/2858987/blog/1552024

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值