问题描述
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());结果为:false,trueString 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());结果为:true,true求指点。
解决方案
你的测试不对String x = "java";System.out.println(x == x.intern());这样才是true,因为x,x.intern()都是指向pool的内存String str1 = new StringBuilder("ja").append("va").toString(); System.out.println(str1 == str1.intern()); 这才是false,因为str1指向堆内存(new的原因),str1.intern()指向的是pool的内存
解决方案二:
楼主的测试结果是没问题的。在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()); // falseString str2 = new String("5678"); System.out.println(str2 == str2.intern()); // false难道只有调了StringBuilder的append方法才会把值写入常量池?
解决方案三:
intern() 是将现在的字符串放入到字符串常量池中。而“==”比较的是对象的引用地址,s1指向的是堆内存中的地址,而另外一个是常量池中的对象,所以返回的应该都是false。
解决方案四:
一般第一次调用intern()时会把该String放入缓存池中进行缓存,因为"java"是关键字,之前很可能缓存池中已经存在了,所以用==判断肯定为false,其他的如果是第一次调用,intern()方法返回的即为该String本身,所以为true。(另外吐槽一下iteye,我新手怎么了,每次都需要回答你那破测试,把我辛苦打的回复都搞没了,怪不得论坛都没人,快倒闭了,我FK!)
解决方案五:
你的测试是错误的,intern是将String置入pool,第一次的时候,肯定pool是没有的,所有应该都是false
解决方案六:
我运行所有都是false啊