大家好,朽木君又回来了!今天为大家介绍一下String Pool。
一、什么是String Pool?
JVM为了提升性能和减少内存开销,避免字符串的重复创建,其维护了一块特殊的内存空间,字符串池(String Pool)。
二、String str="i"与 String str=new String(“i”)一样吗?
不一样,因为内存的分配方式不一样。String str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String(“i”) 则会被分到堆内存中。
我们来看看例子:
String str1 = "aaa";
String str2 = "aaa";
System.out.println(str1==str2); //true
插播==的小知识:
对基本类型:比较的是值是否相同;对引用类型:比较的是引用是否相同;(代码中str1和str2属于对象、引用)
大家看一下,这里str1与str2指向同一个对象,因为str1创建后"aaa"已经放入String Pool中,所以str2会直接引用"aaa";
String str1 = "aaa";
String str2 = new String("aaa");
System.out.println(str1==str2); //1、false
System.out.println(str1=="aaa"); //2、true
System.out.println(str2=="aaa"); //3、false
在这str2会被分到堆内存中,而不是从String Pool中进行引用,所以第一个为false。
把视线移到最后两行代码,程序会先在String Pool中寻找"aaa"是否存在,存在则直接用,不存在就新创建一个,此时String Pool中已经存在了"aaa",并且被str1引用,所以第二个true。
第三个str2创建的对象在堆内存,不是常量池中的"aaa",所以false。所以有的小伙伴遇到new String后进行==操作,发现返回false,感觉莫名其妙的话,不用看 就是这个原因了。
三、String Pool的范围 and 字符串连接问题
话不多说,给各位大人上例子:
package test;
public class Interview {
public static void main(String[] args) {
String hello="Hello",lo = "lo";
String world = new String("aaa");
System.out.println(hello=="Hello"); //1、true
System.out.println(Other.hello==hello); //2、true
System.out.println(other.Other.hello==hello); //3、true
System.out.println(hello==("Hel"+"lo")); //4、true
System.out.println(hello==("hel"+lo)); //5、false
}
}
class Other{
static String hello = "Hello";
}
package other;
public class Other {
public static String hello = "Hello";
}
由例子可以看出 第1个——同一个包同一个类,第1个——同一个包不同类,第3个——不同的包,这三种情况字符串常量的引用指向同一个字符串对象;
由4、5两个例子,可以验证:
(1)常量表达式(不含引用)计算出的字符串是在编译时进行计算,然后被当作常量。
(2)含有引用的字符串拼接是在运行时新创建出来的
讲了这么多,其实告诉我们判断字符串相等还是用equals()最方便了。但如果小伙伴们向更进一步,当高级程序员(听说大厂可能问到这类问题),这部分知识必须要了解的。
那么,再温馨提示一下,如果进行了new String()或者 str1 + str2这种引用表达式,非要用==进行判断,那么动手试试intern()吧!
今天的分享到这结束了,如果有不足的地方大家可以提提改进意见,朽木君很乐意做出改变。可以的话再给个赞啊,给卑微辛劳的大学生一点鼓励o(╥﹏╥)o