先上点题吧
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));
附上答案:
咱们一个个来讲解吧:
1.
str1 == str2 就是 String str1 = "计算机"; 发现常量池没有,那就在堆里新建一个对象,并且把对象的引用保存到常量池,String str2 = "计算机" 发现常量池有这个字符串的引用,直接拿到对象引用
2.
str1 == str3 String str3 = new String("计算机"); 这里涉及到创建多少个对象,前面的代码常量池里面有字符串的引用了,所以在堆里创建一个对象引用并且引用指向常量池的字符串引用
3.
str1 == str3.intern() intern用法: (1) 当常量池中不存在"计算机"这个字符串的引用,将这个对象的引用加入常量池,返回这个对象的引用。 (2) 当常量池中存在"计算机"这个字符串的引用,返回这个对象的引用;
str1 本身的引用就是常量池该字符串的引用,按照:当常量池中存在"计算机"这个字符串的引用,返回这个对象的引用
上面为true,所以 str2 == str3.intern() 也为true.
4.
str3 == str4
String str3 = new String("计算机"); String str4 = new String("计算机"); 他们都是新建一个新的对象,所以不相等,不过他们指向常量池字符串引用是一样的。 即 str3.intern() == str4.intern() 为true.
5.
str5.intern() == str5 str5是通过StringBuilder构建的 在new StringBuilder(“软件”).append(“工程”).toString方法运行后,"软件工程"这个字符串对象才第一次出现。执行了intern方法后str5才被放到常量池中,此时str5跟str5.intern是同一个对象。
6.
str6.intern() == str6 str6是作为对照组出现,这里为了确认StringBuilder 在toString方法执行后会不会把最终字符串放进常量池。很显然并没有,所以str6的intern才会跟str6是同一个对象