原文地址:深入理解JVM(三)-JVM中的常量池
JVM的常量池主要有以下几种:
- 运行时常量池
- 字符串常量池
- 基本类型包装类常量池
- class文件常量池
他们之间的关系:

图解说明:
-
每个class的字节码文件中都有一个常量池,里面是编译后即知的该class会用到的字面量与符号引用,这就是class文件常量池。JVM加载class,会将其类信息,包括class文件常量池置于方法区中。
-
class类信息及其class文件常量池是字节码的二进制流,它代表的是一个类的静态存储结构,JVM加载类时,需要将其转换为方法区中的java.lang.Class类的对象实例;同时,会将class文件常量池中的内容导入运行时常量池。
-
运行时常量池中的常量对应的内容只是字面量,比如一个"字符串",它还不是String对象;当Java程序在运行时执行到这个"字符串"字面量时,会去字符串常量池里找该字面量的对象引用是否存在,存在则直接返回该引用,不存在则在Java堆里创建该字面量对应的String对象,并将其引用置于字符串常量池中,然后返回该引用。
-
Java的基本数据类型中,除了两个浮点数类型(Float、Double),其他的基本数据类型都在各自内部实现了常量池,但都在[-128~127]这个范围内。
class文件常量池
首先我们通过一个简单的类来了解class文件常量池
package com.mazai.learning.jvm;
public class Student {
private final String name = "张三";
private final int entranceAge = 18;
private String evaluate = "优秀";
private int scores = 95;
private Integer level = 5;
public String getEvaluate() {
return evaluate;
}
public void setEvaluate(String evaluate) {
String tmp = "+";
this.evaluate = evaluate + tmp;
}
public int getScores() {
return scores;
}
public void setScores(int scores) {
final int base = 10;
System.out.println("base:" + base);
this.scores = scores + base;
}
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
}
使用反编译命令:javap -verbose Student.class
Classfile /D:/ideaspace/mazai-learning/mazai-jvm/target/classes/com/mazai/learning/jvm/Student.class
Last modified 2022-9-27; size 1581 bytes
MD5 checksum 361fea8d9e4c6966a3a2b295310f3a18
Compiled from "Student.java"
public class com.mazai.learning.jvm.Student
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1

本文详细介绍了JVM中的常量池,包括class文件常量池、运行时常量池和字符串常量池。在JVM加载class时,class文件常量池内容会导入运行时常量池,而运行时常量池具有动态性,可以添加运行时生成的常量。字符串常量池在逻辑上属于方法区,用于存储字符串字面量的引用。String对象的创建和存储涉及字面量赋值、new String()以及String.intern()方法。封装类如Integer也有常量池,范围限制在[-128, 127]之间。"
104288506,7441174,配置静态路由解决多路由连通性问题,"['网络配置', '路由协议', '网络连通性', '静态路由配置']
最低0.47元/天 解锁文章
1258

被折叠的 条评论
为什么被折叠?



