目录
- 1.什么是常量池?
- 2.为什么需要常量池?
- 3.运行时常量池
1.什么是常量池?
1.字节码文件中有个constant pool
,就是常量池
2.当字节码文件被加载到内存中之后,方法区中会存放字节码文件的constant pool
相关信息,这时候就成为了运行时常量池
3.常量池保存了各种字面量和对类型、域和方法的符号引用。
4.常量池可以看做是一张表,虚拟机指令根据这张表找到要执行的方法名、类名、参数类型、字面量等类型。
2.为什么需要常量池?
1.一个java
源文件中的类、接口,编译后会产生一个字节码文件,而java
中的字节码文件需要其他的数据支撑,通常这种数据很大,不能直接存放到字节码里面。所以把对这些数据的引用存放到常量池,在真正需要使用的时候,通过动态链接将符号引用转换为直接引用。
例子:
package jvm;import java.io.Serializable;public class MethodInnerStrucTest extends Object implements Comparable<String>,Serializable {public int num &#61; 10;private static String str &#61; "测试方法的内部结构";public void test1(){int count &#61; 20;System.out.println("count &#61; " &#43; count);}&#64;Overridepublic int compareTo(String o) {return 0;}
}
使用javap -v MethodInnerStrucTest
反编译上面的java
代码产生的class
文件&#xff0c;得到下面的输出。
其中&#xff1a;Constant pool
就是常量池。
常量池中存储的符号引用&#xff0c;在程序运行的时候&#xff0c;会被转换为直接引用。
例如&#xff1a;test1()
方法的字节码 3: getstatic #30 // Field
&#xff0c; #30
就会引用到Constant pool
里面的 #30 &#61; Fieldref #31.#33 //
&#xff0c;程序运行的时候&#xff0c;就会直接进行转换。
Classfile /Users/simple/Documents/IBM/JVM/JVM/bin/jvm/MethodInnerStrucTest.classLast modified Jul 21, 2020; size 1250 bytesMD5 checksum 640842329ae45580b8fa6414cdc50a03Compiled from "MethodInnerStrucTest.java"
public class jvm.MethodInnerStrucTest extends java.lang.Object implements java.lang.Comparable.lang.String>, java.io.Serializableminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER
Constant pool:...
{public int num;descriptor: Iflags: ACC_PUBLIC...public void test1();descriptor: ()Vflags: ACC_PUBLICCode:stack&#61;4, locals&#61;2, args_size&#61;10: bipush 202: istore_13: getstatic 6: new 9: dup10: ldc 12: invokespecial 15: iload_116: invokevirtual 19: invokevirtual 22: invokevirtual 25: returnLineNumberTable:line 12: 0line 13: 3line 14: 25LocalVariableTable:Start Length Slot Name Signature0 26 0 this Ljvm/MethodInnerStrucTest;3 23 1 count I...
}
3.运行时常量池
掌握两点&#xff1a;
1.常量池指的是字节码文件中的Constant pool
部分。这部分内容被类加载之后&#xff0c;存放到方法区的运行时常量池中。
2.运行时常量池具有动态性。也就是在方法区中的运行时常量池是可以发生变化的。而常量池就不行&#xff0c;它是静态的&#xff0c;当编译生成字节码文件直接就不变了。
更多JVM文章请访问我的JVM专栏&#xff1a;
https://blog.csdn.net/u011069294/category_10113093.html