intern()方法的使用
如何保证声明了一个变量他指向的是常量池中的内容呢?
主要有两种方式:
//方式1 : 采用字面量定义
String s = "abc";
//方式二: 调用intern() 方法
String s1 = new String("abc").intern();
String s2 = new StringBuffer("abc").toString().intern();
String s3 = new StringBuilder( "abc").toString().intern();
下面看一个难点面试题
输出程序在JDK1.6 和 JDK 1.7/1.8 中的结果??
public class stringDemo2 {
public static void main(String[] args) {
String s1 = new String("1");
s1.intern();
String s2 = "1";
System.out.println(s1 == s2);//jdk1.6 :false jdk1.7 fase
String s3 = new String("1") + new String("1");
s3.intern();
String s4 = "11";
System.out.println(s3 == s4); // jdk1.6 fasle jdk1.7 true
}
}
JDK1.6
分析
String s1 = new String(“1”); 这行代码创建了两个对象,new的时候再堆中创建了一个对象,然后把该对象再放入到常量池中
s1.intern();在执行这行代码的时候,其实常量池中已经存在了"1"
String s2 = “1”;这行代码先去常量池中查找有没有"1"有的话指向1
String s3 = new String(“1”) + new String(“1”);//s3此时纪录的地址值 new String(“11”);此时常量池中并没有"11"
s3.intern();//将"11"保存在常量池中
String s4 = “11”;
分析
首先要明白在JDK1.7以后,将常量池从永久代移到了堆中.
分析
String s1 = new String(“1”); 这行代码创建了两个对象,new的时候再堆中创建了一个对象,然后把该对象再放入到常量池中
s1.intern();在执行这行代码的时候,其实常量池中已经存在了"1"
String s2 = “1”;这行代码先去常量池中查找有没有"1"有的话指向1
分析
String s3 = new String(“1”) + new String(“1”);//s3此时纪录的地址值 new String(“11”);此时常量池中并没有"11"
s3.intern();//在JDK1.7中,将常量池移到了堆中,所以不会将"11"放到常量池中,常量池中纪录的是堆中s3的地址
String s4 = “11”; //这行代码就不是指向常量值中的对象了,而是指向常量池中保存s3的地址值,所以在JDK1.7中会返回true;