public static void main(String[] args) {
String str1 = new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern() == str1);
String str2 = new StringBuffer("ja").append("va").toString();
System.out.println(str2.intern() == str2);
}
结果:
true
false
第一个打印true
,第二个打印false
。为什么结果不同?
答案 0 :(得分:20)
行为上的差异与StringBuilder
和StringBuffer
之间的差异无关。
String#intern()
的javadoc声明它返回
调用实习方法时,如果池已包含 字符串等于
String
确定的此equals(Object)
对象 方法,然后返回池中的字符串。否则,这个String
对象已添加到池中,对此String
的引用 返回对象。
从
创建的String
String str2 = new StringBuffer("ja").append("va").toString();
是一个全新的String
,不属于该池。
对于
str2.intern() == str2
要返回false
,intern()
调用必须返回不同的参考值,即。 String
"java"
已经在游泳池中。
在第一次比较中,String
“计算机软件”不在调用intern()
的字符串池之前中。因此intern()
返回与str2
中存储的引用相同的引用。因此,引用相等str2 == str2
将返回true
。
答案 1 :(得分:4)
因为您的作业不会从intern pool重新读取而且Java General error: 1 no such index: stores_category_id_index (SQL: DROP INDEX stores_category_id_index)
是不可变的。考虑
String
输出(正如您所料)
String str1 = new StringBuilder("计算机").append("软件").toString();
String str1a = new String(str1); // <-- refers to a different String
str1 = str1.intern();
str1a = str1a.intern();
System.out.println(str1a == str1);
String str2 = new StringBuffer("ja").append("va").toString();
String str2a = new String(str2); // <-- refers to a different String
str2 = str2.intern();
str2a = str2a.intern();
System.out.println(str2a == str2);
答案 2 :(得分:1)
之前提到的有关该池的大量答案,并使用Oracle链接文档进行了非常清楚的解释。
我只想指出我们在调试代码时可以检查的方式。
String str1 = new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern() == str1);//the str1.intern() returns the same memory address the str1
String str2 = new StringBuffer("ja").append("va").toString();
System.out.println(str2.intern() == str2);//the str2.intern() does not return the same memory address the str2
您可以使用任何IDE和debug来检查str1和str1.intern()/ str2和str2.intern()的实际地址。
答案 3 :(得分:0)
让我添加一些更有趣的内容:
所以我认为正确的答案是:
不同供应商的jvm或jvm版本可能具有不同的实现(语言规范不强制执行该操作)
在Oracle JDK 8中(我想您正在使用): 字符串“ java”已在池中(由java.lang.Version#laucher_name加载),并且字符串池仅存储引用,而不存储对象。
但是在OpenJDK中,laucher_name是“ openJDK”;在Oracle JDK 6及更低版本中,字符串池会将字符串对象复制到其目录中。