作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三个问题,去理解字符串常量池:
代码:从字符串常量池中获取相应的字符串
String str1 = “hello”; String str2 = “hello”; System.out.printl("str1 == str2" : str1 == str2 ) //true
在分析字符串常量池的位置时,首先了解一下堆、栈、方法区:
字符串常量池则存在于方法区
代码:堆栈方法区存储字符串
String str1 = “abc”; String str2 = “abc”; String str3 = “abc”; String str4 = new String(“abc”); String str5 = new String(“abc”);
字符串对象的创建
面试题:String str4 = new String(“abc”) 创建多少个对象?
所以,常量池中没有“abc”字面量则创建两个对象,否则创建一个对象,以及创建一个引用
根据字面量,往往会提出这样的变式题:
String str1 = new String(“A”+”B”) ; 会创建多少个对象? String str2 = new String(“ABC”) + “ABC” ; 会创建多少个对象?
str1: 字符串常量池:”A”,”B”,”AB” : 3个 堆:new String(“AB”) :1个 引用: str1 :1个 总共 : 5个
str2 : 字符串常量池:”ABC” : 1个 堆:new String(“ABC”) :1个 引用: str2 :1个 总共 : 3个
代码:基础类型的变量和常量,变量和引用存储在栈中,常量存储在常量池中
int a1 = 1; int a2 = 1; int a3 = 1; public static int INT1 =1 ; public static int INT2 =1 ; public static int INT3 =1 ;
String str1 = “hello”; String str2 = “hello”; System.out.printl("str1 == str2" : str1 == str2 ) //true
通过new操作符创建的字符串对象不指向字符串池中的任何对象,但是可以通过使用字符串的intern()方法来指向其中的某一个。java.lang.String.intern()返回一个保留池字符串,就是一个在全局字符串池中有了一个入口。如果以前没有在全局字符串池中,那么它就会被添加到里面
// Create three strings in three different ways. String s1 = "Hello"; String s2 = new StringBuffer("He").append("llo").toString(); String s3 = s2.intern(); // Determine which strings are equivalent using the == // operator System.out.println("s1 == s2? " + (s1 == s2)); // false System.out.println("s1 == s3? " + (s1 == s3)); // true
字符串对象内部是用字符数组存储的,那么看下面的例子:
String m = "hello,world"; String n = "hello,world"; String u = new String(m); String v = new String("hello,world");
使用图来表示的话,情况就大概是这样的(使用虚线只是表示两者其实没什么特别的关系):
测试demo:
String m = "hello,world"; String n = "hello,world"; String u = new String(m); String v = new String("hello,world"); System.out.println(m == n); //true System.out.println(m == u); //false System.out.println(m == v); //false System.out.println(u == v); //false
结论:
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/101457.html原文链接: