先明确一个概念:String s = new String( "1" );
jvm的处理如下:"new String( "1" ) " 将在java 堆中生成,同时"1"在字符池中生成,堆对象生成s(对象的引用)存在虚拟机栈。
s.inturn():
jdk1.6 下调用s.intern(),此时返回值还是字符串"SEU_Calvin",表面上看起来好像这个方法没什么用处。 但实际上,在JDK1.6中它做了个小动作:检查字符串池里是否存在"SEU_Calvin"这么一个字符串,如果存在,就返回池里的字符串 如果不存在,该方法会把"SEU_Calvin"添加到字符串池中,然后再返回它的引用
jdk1.7 下调用s.intern(),存在下相同;不存在时,生成一个指向堆内对象的引用。
直接上代码解析。
String s = new String( "1" ); //堆中生成一个1 的object 和字符池中生成"1" s.intern(); //没起作用,因为字符池中已经有"1" String s2 = "1" ; //返回的是指向字符池的"1" System.out.println(s == s2); //一个指向堆中的对象,一个指向字符池,怎么会相等。 String s3 = new String( "1" ) + new String( "1" ); //堆中生成一个"1"的对象,并且在字符池中生成一个"1" s3.intern();//s3因为其不可变性,拼接后的string会指向最后生成的对象,即"11".但是此时字符池中没有"11",所以会在字符池中生成对象"11"(jdk1.6)/对象的引用(jdk1.7) String s4 = "11" ; //jdk1.6 s4是字符池中的"11",jdk1.7下s4是指向堆中的"11"对象的引用。 System.out.println(s3 == s4); //jdk1.6下,不等 jdk1.7下,相等
输出结果为:
JDK1. 6 以及以下: false false JDK1.7 以及以上: false true
再分别调整上面代码2.3行、7.8行的顺序:
String s = new String( "1" ); //堆中生成一个1 的object 和字符池中生成"1" String s2 = "1" ; //返回字符池中的"1" s.intern(); //不起作用 System.out.println(s == s2); //不等 String s3 = new String( "1" ) + new String( "1" ); //堆中生成一个"1"的对象,并且在字符池中生成一个"1" (但是s3最终指向的是"11") String s4 = "11" ; //字符池中生成 "11" s3.intern(); //不起作用 System.out.println(s3 == s4); //不等
输出结果为:
JDK1. 6 以及以下: false false JDK1.7 以及以上: false false
以上;