日期:2014-05-20  浏览次数:20928 次

java常量池
常量池里面的东西是什么时候添加进去的呀,是源代码被编译成.class文件的时候,还是也要包括jvm解释执行.class的时候产生的呢???
------解决方案--------------------
编译期吧。就像你定义String s="str";在编译期"str"就是可识别的常量,就能加进常量池中了。
------解决方案--------------------
什么是常量池?

每个类都有自己的常量池。常量池类似于数组,通过索引来访问。常量池放了什么东西?放了方法名、方法描述符、类名、字段名,字段描述符,常量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;