new String(“abc”);创建了什么?
堆:一个abc对象
常量池:如果没有abc则创建一个abc
String S= new String(“a”) + “b”; 创建了多少对象?
堆:new String(“a”) 和 ab两个对象
常量池常量:a,b(**注意:**没有ab)
引用:S
intern方法作用
(1) 当常量池中不存在"abc"这个字符串的引用,将这个对象的引用加入常量池,返回这个对象的引用。
(2) 当常量池中存在"abc"这个字符串的引用(堆中的一个对象),返回这个对象的引用;
String.intern()分析
- 判断这个常量是否存在于常量池。
- 如果存在
判断存在内容是引用还是常量,
如果是引用,
返回引用地址指向堆空间对象,
如果是常量,
直接返回常量池常量
- 如果不存在,
将当前对象引用复制到常量池,并且返回的是当前对象的引用
1. 只在常量池上创建【常量】
(注:字符串常量池在jdk1.8中放到了堆中,所以字符串常量池中存储的内容也称之为对象。)
String str0 = "计算机";
String str1 = "abc" + "def";
2. 只在堆上创建对象
String拼接字符串:字符串的拼接又分为变量拼接和已知字符串的拼接。
只要拼接的内容中存在变量,那么拼接后的新变量就是在堆内存中创建的一个对象实体,而不会在字符串中创建新对象。
常量的拼接:不会在堆中创建对象,如果常量池没有拼接后的字符串,会在常量池中创建字符串常量。
String str2 = new String("A") + new String("A");
String str11 = "信号" + new String("123");
String str3 = new StringBuilder("软件").append("工程").toString();
String str4 = new String(new StringBuilder("物联网").append("工程").toString());
String str5 = new String("信号"+str2);
3.在堆上创建对象,在常量池上创建常量
String str6 = new String("计算机");
String str8 = new String("信号"+"系统");
String str8 = new String(new StringBuilder("物联网+++").toString());
4.在堆上创建对象,在常量池上创建引用
String a4 = new String("A") + new String("A");//只在堆上创建对象AA
a4.intern();//将该对象AA的引用保存到常量池上
5.在堆上创建对象,在常量池上创建引用, 在常量池上创建常量(不可能)
String a5 = new String("A") + new String("A");//只在堆上创建对象
a5.intern();//在常量池上创建引用
String a6 = "AA";//此时不会再在常量池上创建常量AA,而是将a5的引用返回给a6
System.out.println(a5 == a6); //true
验证
String str1 = "计算机";
String str2 = "计算机";
System.out.println("str1==str2:" + (str1 == str2));
String str3 = new String("计算机");
System.out.println("str1==str3:" + (str1 == str3));
System.out.println("str1==str3.intern():" + (str1 == str3.intern()));
System.out.println("str2==str3.intern():" + (str2 == str3.intern()));
String str4 = new String("计算机");
System.out.println("str3==str4:" + (str3 == str4));
System.out.println("str3.intern()==str4.intern():" + (str3.intern() == str4.intern()));
String str5 = new StringBuilder("软件").append("工程").toString();
System.out.println("str5.intern() == str5:" + (str5.intern() == str5));
String str6 = new String(new StringBuilder("物联网").append("工程").toString());
System.out.println("str6.intern() == str6:" + (str6.intern() == str6));
String str7 = new String("物联网---");
System.out.println("str7.intern() == str7:" + (str7.intern() == str7));
String str8 = new String(new StringBuilder("物联网+++").toString());
System.out.println("str8.intern() == str8:" + (str8.intern() == str8));
String str9 = new String("信号"+"系统");
System.out.println("str9.intern() == str9:" + (str9.intern() == str9));
String str10 = new String("信号"+str7);
System.out.println("str10.intern() == str10:" + (str10.intern() == str10));
str1==str2:true
str1==str3:false
str1==str3.intern():true
str2==str3.intern():true
str3==str4:false
str3.intern()==str4.intern():true
str5.intern() == str5:true
str6.intern() == str6:true
str7.intern() == str7:false
str8.intern() == str8:false
str9.intern() == str9:false
str10.intern() == str10:true
参考:
https://www.cnblogs.com/think-in-java/p/10418915.html
https://blog.csdn.net/guoxiaolongonly/article/details/80425548