Java 常量池详解之class文件常量池 和class运行时常量池
在Java中,常量池是指在编译阶段确定的一些数据,这些数据包括了代码中用到的字符串、数字等等。在程序运行的时候,这些常量会被加载到JVM的内存中进行使用。Java中的常量池主要包括class文件常量池和class运行时常量池两种。
class文件常量池
class文件常量池是指,编译期间生成的.class文件中记录的所有常量的表格形式的容器。class文件常量池是class文件的一部分,其中记录了编译后生成的字节码文件中所引用的各种常量、各种类型的符号引用和一些字节码指令。它可以看作是在编译时将各种符号和常量“映射”到常量池中。
例如,下面是一个Java代码示例:
public class MyClass {
public static final String MY_CONSTANT = "constant value";
}
编译后的.class文件会包含对MY_CONSTANT常量的引用,在class文件常量池中的记录如下:
[CONSTANT_UTF8, constant value]
[CONSTANT_CLASS, MyClass]
[CONSTANT_FIELDREF, MyClass.MY_CONSTANT]
其中,CONSTANT_UTF8表示常量的类型,第二个元素是存储的常量值;CONSTANT_CLASS表示类的类型,第二个元素是类名;CONSTANT_FIELDREF表示字段的类型,第二个元素是字段所在的类名和字段名。
class运行时常量池
在类加载的时候,class文件常量池中的内容会被加载到JVM的内存中生成class运行时常量池,用于存储当前类和其父类的各种常量、符号引用等信息。class运行时常量池包括两类常量:字面量和符号引用。
字面量包括字符串、数字和布尔类型等常量。例如,下面是一个Java代码示例:
public class MyClass {
String a = "hello";
int b = 3;
double c = 3.14;
boolean d = true;
}
在class运行时常量池中的记录如下:
[CONSTANT_UTF8, hello]
[CONSTANT_UTF8, a]
[CONSTANT_UTF8, Ljava/lang/String;]
[CONSTANT_UTF8, b]
[CONSTANT_UTF8, I]
[CONSTANT_UTF8, c]
[CONSTANT_UTF8, D]
[CONSTANT_UTF8, d]
[CONSTANT_UTF8, Z]
[CONSTANT_CLASS, MyClass]
[CONSTANT_DOUBLE, 3.14]
[CONSTANT_INTEGER, 3]
[CONSTANT_UTF8, <init>]
[CONSTANT_UTF8, ()V]
[CONSTANT_METHODREF, MyClass.<init>]
[CONSTANT_UTF8, Code]
[CONSTANT_NAMEANDTYPE, a, Ljava/lang/String;]
[CONSTANT_NAMEANDTYPE, b, I]
[CONSTANT_NAMEANDTYPE, c, D]
[CONSTANT_NAMEANDTYPE, d, Z]
其中,CONSTANT_DOUBLE和CONSTANT_INTEGER表明了数字类型,第二个元素是具体的数值。CONSTANT_METHODREF表示方法引用,第二个元素是方法所在的类名和方法名。CONSTANT_NAMEANDTYPE表示字段名和字段类型。
符号引用包括类、字段和方法三种。例如,下面是一个Java代码示例:
public class MyClass {
static final String MY_CONSTANT = "constant value";
int a = MyClass.MY_CONSTANT.length();
void b(MyClass myClass) {
String s = myClass.a;
}
}
在class运行时常量池中的记录如下:
[CONSTANT_UTF8, constant value]
[CONSTANT_UTF8, MY_CONSTANT]
[CONSTANT_UTF8, Ljava/lang/String;]
[CONSTANT_FIELDREF, MyClass.MY_CONSTANT]
[CONSTANT_UTF8, a]
[CONSTANT_UTF8, I]
[CONSTANT_UTF8, <init>]
[CONSTANT_UTF8, ()V]
[CONSTANT_METHODREF, MyClass.<init>]
[CONSTANT_UTF8, b]
[CONSTANT_UTF8, (LMyClass;)V]
[CONSTANT_UTF8, s]
[CONSTANT_NAMEANDTYPE, <init>, ()V]
[CONSTANT_UTF8, Code]
[CONSTANT_NAMEANDTYPE, length, ()I]
[CONSTANT_NAMEANDTYPE, a, Ljava/lang/String;]
[CONSTANT_METHODREF, java/lang/String.length]
[CONSTANT_FIELDREF, MyClass.a]
[CONSTANT_NAMEANDTYPE, b, (LMyClass;)V]
其中,CONSTANT_FIELDREF和CONSTANT_METHODREF表示字段和方法引用,第二个元素是字段或方法所在的类名和字段或方法名。
以上是Java 常量池详解之class文件常量池 和class运行时常量池的全部内容。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 常量池详解之class文件常量池 和class运行时常量池 - Python技术站