使用三种方式创建三个对象,判断对象是否相等。

String str1= "abc";
String str2= new String("abc");
String str3= str2.intern();
System.out.print(str1==str2);
System.out.print(str2==str3);
System.out.print(str1==str3)

一、String 对象的不可变性有什么好处:
1:保证了String对象的安全性,防止被恶意修改。
2:保证 hash 属性值不会频繁变更,确保了唯一性,使得类似HashMap容器可以实现key-value缓存功能。
3:可以实现字符串常量池。如String str = “abc” 。这种方法创建对象,JVM首先会检查常量池是否有该对象,如果在则返回该对象的引用,否则在常量池创建新的字符串。这可以减少同一个值的字符串的重复创建已到达节约内存的目的。

二、做字符串拼接时,尽量显示的使用StringBuilder提升系统性能,因为即使使用的是+来拼接字符串,编译器也会优化为StringBuilder的方式;如果涉及到线程安全则可以使用StringBuffer。

三、String.intern 节省内存

String a =new String("abc").intern();
String b = new String("abc").intern();
System.out.print(a==b);

结果是true
因为字符串常量的创建时放在常量池的;字符串变量对象是创建在堆内存的,同时在常量池创建一个字符串对象并且复制到堆内存对象中,返回堆内存对象的引用。
intern 方法,字符串变量会在常量池查看是否有等于该对象的字符串,如果没有就在常量池新增该对象,并返回对象的引用;如果有就直接返回对象的引用。堆内存原用的对象由于没有引用指向它则被回收。
上面的列子,创建a变量,首先在堆内存创建一个对象,然后在常量池创建一个对象,调用intern方法会去常量池查找有没有该对象,有就直接返回引用。
创建b字符串变量时,会在堆内存创建一个对象,此时常量池已经存在该对象不再创建。调用intern方法,在常量池查找到该对象,直接返回引用。所有a和b引用的是同一个对象。

使用intern方法要把握一个度,如果对空间要求高于时间且存在大量的重复字符串,可以考虑使用常量池存储。
如果对查询速度要求很高且字符串的数量很大,重复率低的情况下,不建议使用常量池。

开始答案是false,false,true。
1、String str1 = “abc”;通过字符串常量的方式创建,abc存储于字符串常量池中;
2、String str2 = new String(“abc”);通过字符串变量的方式创建,引用地址存放在堆内存中,abc则存放在字符串常量池中;所以str1 == str2是false
3、String str3 = str2.intern();由于str2调用了intern()方法,会返回常量池中的数据,地址直接指向常量池,所以str1 == str3;而str2和str3地址值不等所以也是false(str2指向堆空间,str3直接指向字符串常量池)。