先看下面的代码:java
String s = new String("1");
String s1 = s.intern();
System.out.println(s == s1);
复制代码
打印结果为:
false
复制代码
对于new String("1")
,会生成两个对象,一个是String类型对象,它将存储在Java Heap中,另外一个是字符串常量对象"1",它将存储在字符串常量池中。 s.intern()
方法首先会去字符串常量池中查找是否存在字符串常量对象"1",若是存在则返回该对象的地址,若是不存在则在字符串常量池中生成为一个"1"字符串常量对象,并返回该对象的地址。 以下图: bash
s
指向的是Stirng类型对象,变量
s1
指向的是"1"字符串常量对象,因此
s == s1
结果为false。
在上面的基础上咱们再定义一个s2以下:微信
String s = new String("1");
String s1 = s.intern();
String s2 = "1";
System.out.println(s == s1);
System.out.println(s1 == s2); // true
复制代码
s1 == s2
为true,表示变量s2是直接指向的字符串常量,以下图: 学习
在上面的基础上咱们再定义一个t以下:优化
String s = new String("1");
String t = new String("1");
String s1 = s.intern();
String s2 = "1";
System.out.println(s == s1);
System.out.println(s1 == s2);
System.out.println(s == t); // false
System.out.println(s.intern() == t.intern()); // true
复制代码
s == t
为false,这个很明显,变量s和变量t指向的是不一样的两个String类型的对象。 s.intern() == t.intern()
为true,由于intern方法返回的是字符串常量池中的同一个"1"对象,因此为true。spa
在上面的基础上咱们再定义一个x和s3以下:code
String s = new String("1");
String t = new String("1");
String x = new String("1") + new String("1");
String s1 = s.intern();
String s2 = "1";
String s3 = "11";
System.out.println(s == s1);
System.out.println(s1 == s2);
System.out.println(s == t);
System.out.println(s.intern() == t.intern());
System.out.println(x == s3); // fasle
System.out.println(x.intern() == s3.intern()); // true
复制代码
变量x为两个String类型的对象相加,由于x != s3
,因此x确定不是指向的字符串常量,实际上x就是一个String类型的对象,调用x.intern()
方法将返回"11"对应的字符串常量,因此x.intern() == s3.intern()
为true。cdn
将上面的代码简化并添加几个变量以下:对象
String x = new String("1") + new String("1");
String x1 = new String("1") + "1";
String x2 = "1" + "1";
String s3 = "11";
System.out.println(x == s3); // false
System.out.println(x1 == s3); // false
System.out.println(x2 == s3); // true
复制代码
x == s3
为false表示x指向String类型对象,s3指向字符串常量; x1 == s3
为false表示x1指向String类型对象,s3指向字符串常量; x2 == s3
为true表示x2指向字符串常量,s3指向字符串常量;blog
因此咱们能够看到new String("1") + "1"
返回的String类型的对象。
如今咱们知道intern方法就是将字符串保存到常量池中,在保存字符串到常量池的过程当中会先查看常量池中是否已经存在相等的字符串,若是存在则直接使用该字符串。 因此咱们在写业务代码的时候,应该尽可能使用字符串常量池中的字符串,好比使用String s = "1";
比使用new String("1");
更节省内存。咱们也可使用String s = 一个String类型的对象.intern();
方法来间接的使用字符串常量,这种作法一般用在你接收到一个String类型的对象而又想节省内存的状况下,固然你彻底能够String s = 一个String类型的对象;可是这么用可能会由于变量s的引用而影响String类型对象的垃圾回收。因此咱们可使用intern方法进行优化,可是须要注意的是intern
能节省内存,可是会影响运行速度,由于该方法须要去常量池中查询是否存在某字符串。
若是以为这篇文章能让你学到知识,可否帮忙转发,将知识分享出去。 若是想第一时间学习更多的精彩的内容,请关注微信公众号:1点25