Java 字符串常量池 及 intern 方法的使用
2023-09-11 14:17:56 时间
参考这篇文章:深入解析String#intern - 美团技术团队 (meituan.com)
jdk7 版本对 intern 操作和常量池都做了一定的修改,主要包括2点:
- 将String常量池 从 Perm 区移动到了 Java Heap区
- String#intern 方法时,如果存在堆中的对象,会直接保存堆中对象的引用,而不会重新创建对象。
下面做一个测试:
1 public static void main(String[] args) { 2 3 /* 4 * new String("a") + new String("b") 在堆和字符串常量池一共传创建了 5 个对象,分别为: 5 * 堆:"a"、"b"、"ab" + 字符串常量池:"a"、"b" 6 * 但 str1 是堆中 "ab" 对象的引用,并非字符串常量池 "ab" 对象的引用 7 * str1.intern() 实际是返回了字符串常量池 "ab" 对象的引用 8 * str3.intern() 也是返回了字符串常量池 "ab" 对象的引用 9 */ 10 11 // 返回堆中 "ab" 对象的引用 12 String str1 = new String("a") + new String("b"); 13 // 在字符串常量池中生成 "ab" 对象并返回其引用 14 String str2 = "ab"; 15 // 返回堆中新生成的 "ab" 对象的引用 16 String str3 = new String("a") + new String("b"); 17 // false, str1.intern() 返回字符串常量池中的引用,str1为堆中的引用,二者不是同一个内存地址 18 System.out.println(str1.intern() == str1); 19 // true, str1.intern() 和 str2 都是堆中同一个对象 "ab" 的引用 20 System.out.println(str1.intern() == str2); 21 // false, str1 和 str3 分别指向了堆中 2 个不同的 "ab" 对象 22 System.out.println(str1 == str3); 23 // true, str1.intern() 和 str3.intern() 都是字符串常量池中同一个对象 "ab" 的引用 24 System.out.println(str1.intern() == str3.intern()); 25 }
另一个测试:
1 public static void main(String[] args) { 2 /* 3 * 直接使用双引号声明出来的 String 对象会直接存储在常量池中,此时堆中生成一个 ”1“ 对象,字符串常量池中也生成一个 ”1“ 对象 4 * 返回的是堆中 ”1“ 对象的引用 5 */ 6 String s = new String("1"); 7 // 此时字符串常量池中已经存在 ”1“ 对象了,所以不会有堆中此对象引用拷贝的操作了 8 s.intern(); 9 // 此时字符串常量池中已经存在 ”1“ 对象了,直接返回字符串常量池中此对象的引用 10 String s2 = "1"; 11 // fasle, s 为堆中对象的引用,s2 为字符串常量池中对象的引用,二者内存地址不一样 12 System.out.println(s == s2); 13 14 // 在堆中生成 3 个对象,分别为 ”1“、”1“、”11“ 并返回堆中对象 ”11“ 的引用,此时常量池中是没有 ”11“ 对象的 15 String s3 = new String("1") + new String("1"); 16 // 把 s3 的引用拷贝到字符串常量池中 17 s3.intern(); 18 // 直接返回字符串常量池中 s3 的引用 19 String s4 = "11"; 20 // true,s3 和 s4 均为字符串常量池中的同一个内存地址 21 System.out.println(s3 == s4); 22 }
相关文章
- 干货--JMS(java消息服务)整合Spring项目案例
- Java抽象类深入理解-----模板方法设计模式(Templete Method)
- java面向对象高级分层实例_测试类(main方法所在的类)
- java中异常注意的细节2
- java中得到classpath和当前类的绝对路径的一些方法(路径中的%20"进行替换空格)
- Java实现 LeetCode 417 太平洋大西洋水流问题
- Java实现 LeetCode 268 缺失数字
- Java中lang包的常用方法介绍
- Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
- Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
- Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
- 最简单的JAVA解析XML字符串方法
- 【JAVA】java中split以"." 、""、“|”分隔字符串
- 【JAVA】Java 异常中e的getMessage()和toString()方法的异同
- java 11 增加了一系列的字符串处理方法,Optional 加强 ,改进的文件API
- Effective Java -- 对于所有对象都通用的方法
- 【JAVA】java中split以"." 、""、“|”分隔字符串
- Java Collection类型的forEach方法
- Java实现获得MySQL数据库中所有表的记录总数可行方法
- Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216 java c# php js.docx
- Java 分割字符串的方法String.split()底层原理与使用
- java 方法 compareTo()的正确使用
- Java 阻塞队列 BlockingQueue 详解: put,add 和 offer 三个方法
- Java构造器和方法的区别
- java入门 常见问题0010-2:方法名不合适