String类intern方法的一个困惑的问题

[code="java"]String str1 = new StringBuilder("ja").append("va").toString();
System.out.println(str1 == str1.intern());
String str2 = new StringBuilder("计算机").append("aa技术").toString();
System.out.println(str2 == str2.intern());[/code]

结果为:false,true

[code="java"]String str1 = new StringBuilder("ja").append("av").toString();
System.out.println(str1 == str1.intern());
String str2 = new StringBuilder("计算机").append("aa技术").toString();
System.out.println(str2 == str2.intern());[/code]
结果为:true,true

求指点。

你的测试不对

[code="java"]
String x = "java";
System.out.println(x == x.intern());
[/code]
这样才是true,因为x,x.intern()都是指向pool的内存

[code="java"]
String str1 = new StringBuilder("ja").append("va").toString();

System.out.println(str1 == str1.intern());

[/code]
这才是false,因为str1指向堆内存(new的原因),str1.intern()指向的是pool的内存

我运行所有都是false啊

你的测试是错误的,intern是将String置入pool,第一次的时候,肯定pool是没有的,所有应该都是false

一般第一次调用intern()时会把该String放入缓存池中进行缓存,因为"java"是关键字,之前很可能缓存池中已经存在了,所以用==判断肯定为false,其他的如果是第一次调用,intern()方法返回的即为该String本身,所以为true。
(另外吐槽一下iteye,我新手怎么了,每次都需要回答你那破测试,把我辛苦打的回复都搞没了,怪不得论坛都没人,快倒闭了,我FK!)

intern() 是将现在的字符串放入到字符串常量池中。而“[color=red]==[/color]”比较的是对象的引用地址,s1指向的是堆内存中的地址,而另外一个是常量池中的对象,所以返回的应该都是[color=red]false[/color]。

楼主的测试结果是没问题的。在JDK7下面就是这个结果。

intern()方法在JDK7里面有了一些改变,如果在JDK6测试,肯定都是false.

由于new StringBuilder("计算机").append("aa技术").toString();创建的字符串
会存在于常量池中。而intern()方法就直接返回了该字符串的引用。

而由于"java"是关键字,已经在常量池中存在了,所以intern()返回的值是JRE
放入的"java"常量的引用,之后StringBuilder创建出来的在堆上,因此用==比较
返回的是false.(见周志明《深入理解Java虚拟机》第二版P57)

但是,我不理解的是:
String str1 = new StringBuilder("1234").toString();

System.out.println(str1 == str1.intern()); // false

String str2 = new String("5678");

System.out.println(str2 == str2.intern()); // false

难道只有调了StringBuilder的append方法才会把值写入常量池?