当前位置:网站首页>Class常量池与运行时常量池
Class常量池与运行时常量池
2022-07-06 21:00:00 【季风泯灭的季节】
class常量池
java文件在编译成class文件后,在class文件中会生成一个常量池,用于存放代码的字面量、符号引用,如static、void、public等等。这个常量池称为class常量池。用javap命令可生成一个可阅读的JVM字节码指令文件:
javap -v ScheduledBlockChainTask.class
红框标出的就是class常量池信息,常量池中主要存放两大类常量:字面量和符号引用。
int a = 1;
int b = 2;
int c = "abcdefg";
int d = "abcdefg
- 类和接口的全限定名
- 字段的名称和描述符
- 方法的名称和描述符
- 为字符串开辟一个字符串常量池,类似于缓存区
- 创建字符串常量时,首先查询字符串常量池是否存在该字符串
- 存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中
- Jdk1.6及之前: 有永久代, 运行时常量池在永久代,运行时常量池包含字符串常量池
- Jdk1.7:有永久代,但已经逐步“去永久代”,字符串常量池从永久代里的运行时常量池分离到堆里
- Jdk1.8及之后: 无永久代,运行时常量池在元空间,字符串常量池里依然在堆里
三种字符串操作
- 直接赋值字符串
String s = "lamu"; // s指向常量池中的引用
- new String();
String s1 = new String("zhuge"); // s1指向内存中的对象引用
- intern方法
String s1 = new String("zhuge");
String s2 = s1.intern();
System.out.println(s1 == s2); //false
intern方法返回的是对象在字符串常量池中的引用。在jdk6及以下的版本中,如果字符串常量池中存在该对象,则返回字符串常量池中对象的引用。如果没有,则将该对象添加到字符串常量池中,返回字符串常量池中该对象的引用。在jdk6以上的版本中,如果字符串常量池中存在该对象,则返回字符串常量池中对象的引用。如果没有,则在堆中查看是否存在该对象,如果有,将堆中该对象的引用放入字符串常量池中并返回。
String拼接符“+”底层会做什么
如果在编译阶段,能确定拼接前后对象的值,那么会在编译阶段直接拼接,将最终的值放入字符串常量池。如果在编译阶段不能知道拼接前后对象的值,那么会在运行阶段创建一个拼接了前后字段值的对象在堆和字符串常量池中。
String s1 = new String("he") + new String("llo");
String s2 = s1.intern();
System.out.println(s1 == s2);
// 在 JDK 1.6 下输出是 false,创建了 6 个对象
// 在 JDK 1.7 及以上的版本输出是 true,创建了 5 个对象
// 当然我们这里没有考虑GC,但这些对象确实存在或存在
// 注意:常量池是否有相应的对象取决于字面量,字面量不存在的对象不会出现在常量池
String s0="hello";
String s1="hello";
String s2="he" + "llo";
System.out.println( s0==s1 ); //true
System.out.println( s0==s2 ); //true s2会在编译期被优化成"hello"。
String s0="hello";
String s1=new String("hello");
String s2="he" + new String("llo");
System.out.println( s0==s1 ); // false s0在常量池,s1在堆中
System.out.println( s0==s2 ); // false new String("llo")没法在编译期优化,所以s2最终在堆中生成
System.out.println( s1==s2 ); // false s1和s2都在堆中,但它们是new出来的两个不同对象
String a = "ab";
String bb = "b";
String b = "a" + bb;
System.out.println(a == b); // false 变量bb在编译期不可知,无法优化
String a = "ab";
final String bb = "b";
String b = "a" + bb;
System.out.println(a == b); // true bb用final修饰,编译期可知,b在编译期可被优化成"ab"
String a = "ab";
final String bb = getBB();
String b = "a" + bb;
System.out.println(a == b); // false 方法即使用final修饰,它也要到运行期来生成动态链接执行代码,因此编译期不可知,无法优化
private static String getBB() {
return "b";
}
String str2 = new StringBuilder("计算机").append("技术").toString();
System.out.println(str2 == str2.intern()); //true
// str2等于堆中的对象"计算机技术",因为没有出现字面量"计算机技术",所以常量池不存在这个对象。
// str2.intern()返回的字符串常量池中对堆对象的引用,所以是同一个对象
String str1 = new StringBuilder("ja").append("va").toString();
System.out.println(str1 == str1.intern()); //false
// java是关键字,在JVM初始化的相关类里放进字符串常量池了。
String s1=new String("test");
System.out.println(s1==s1.intern()); //false
// new出来的对象在常量池中已存在,s1.intern()返回的是常量池中的对象。
//5种整形的包装类Byte,Short,Integer,Long,Character的对象,
//在值小于127时可以使用对象池
Integer i1 = 127; //这种调用底层实际是执行的Integer.valueOf(127),里面用到了IntegerCache对象池
Integer i2 = 127;
System.out.println(i1 == i2);//输出true
//值大于127时,不会从对象池中取对象
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3 == i4);//输出false
//用new关键词新生成对象不会使用对象池
Integer i5 = new Integer(127);
Integer i6 = new Integer(127);
Integer i7 = 127;
System.out.println(i5 == i6);//输出false
System.out.println(i5 == i7);//输出false
//Boolean类也实现了对象池技术
Boolean bool1 = true;
Boolean bool2 = true;
System.out.println(bool1 == bool2);//输出true
//浮点类型的包装类没有实现对象池技术
Double d1 = 1.0;
Double d2 = 1.0;
System.out.println(d1 == d2);//输出false
边栏推荐
- Not All Points Are Equal Learning Highly Efficient Point-based Detectors for 3D LiDAR Point
- Flink task exit process and failover mechanism
- [security attack and Defense] how much do you know about serialization and deserialization?
- VHDL实现任意大小矩阵乘法运算
- QT thread and other 01 concepts
- MySQL storage engine
- 【安全攻防】序列化與反序列,你了解多少?
- 图形化工具打包YOLOv5,生成可执行文件EXE
- ubuntu20安装redisjson记录
- How to customize the shortcut key for latex to stop running
猜你喜欢
华为小米互“抄作业”
VHDL implementation of arbitrary size matrix addition operation
RestClould ETL 社区版六月精选问答
Calculation of time and space complexity (notes of runners)
Top 50 hit industry in the first half of 2022
What is Ba? How about Ba? What is the relationship between Ba and Bi?
Baidu map JS development, open a blank, bmapgl is not defined, err_ FILE_ NOT_ FOUND
线性表的查找
Code quality management
Docker部署Mysql8的实现步骤
随机推荐
About Confidence Intervals
大白话高并发(二)
Depth analysis of compilation constants, classloader classes, and system class loaders
It's too convenient. You can complete the code release and approval by nailing it!
Hisilicon 3559 universal platform construction: RTSP real-time playback support
What is the experience of maintaining Wanxing open source vector database
Function reentry, function overloading and function rewriting are understood by yourself
Under the tide of "going from virtual to real", Baidu AI Cloud is born from real
Delete data in SQL
API data interface of A-share index component data
CMB's written test - quantitative relationship
Flutter3.0, the applet is not only run across mobile applications
概率论公式
Set static IP for raspberry pie
Confirm the future development route! Digital economy, digital transformation, data This meeting is very important
如何替换模型的骨干网络(backbone)
Restcloud ETL Community Edition June featured Q & A
海思3559万能平台搭建:RTSP实时播放的支持
预处理——插值
VHDL实现任意大小矩阵乘法运算