Java String.intern()

在看《深入理解Java虚拟机》第二章中有如下代码:
String str1 = new StringBuilder("计算机").append("软件").toString();
		System.out.println(str1.intern() == str1);

		String str2 = new StringBuilder("ja").append("va").toString();
		System.out.println(str2.intern() == str2);

在不同的jdk上面运行产生不同的结果。
在openjdk 1.8上面运行结果是true/true。
这里不纠结不同jdk运行的结果不同,只谈谈String.intern()方法的机制。
new StringBuilder("计算机").append("软件")
这段代码在执行的时候就会产生2个字符串"计算机"和"软件"并放入string pool中,因此"计算机软件".intern()的时候由于string pool中没有"计算机软件"这个字符串,根据intern()的定义:如果string pool中存在(equals)这个字符串,则返回string pool中的字符串引用,如果不存在,把这个字符串(复制一份)放入string pool并返回这个字符串引用。因此str1.intern() == str1结果就是true。
str2.intern()时候由于string pool中已经存在"java"这个字符串(作者周志明的解释),因此他说返回结果是false,但是在我的机器上返回结果却是true,可能openjdk 1.8里"java"这个字符串并不存在于string pool中 这里不纠结这个。
String str1 = "str1";//字符串常量直接复制一份到string pool
		System.out.println(str1.intern() == str1);//true
		
		String str2 = "str" + "2";//编译时会优化成"str2"
		System.out.println(str2.intern() == str2);//true
		
		String str3 = new String("str3");//这个时候"str3"是字符串常量,已经进入string pool
		System.out.println(str3.intern() == str3);//false
		
		String str3_2 = new String("str") + new String("3");
		System.out.println(str3_2.intern() == str3_2);//false;上面2个字符串str和3是常量,已经放入到string pool,并且"str3"也已经在string pool了(参见前面str3变量)
		
		String str4 = new String("str") + new String("4");
		System.out.println(str4.intern() == str4);//true;这个就不解释了
		
		String str5 = new StringBuilder("str5").toString();//"str5"是字符串常量,已经存入了string pool
		System.out.println(str5.intern() == str5);//false;
		
		String str6 = new StringBuilder("str").append("6").toString();
		System.out.println(str6.intern() == str6);//true;和str4变量一样

上面这些代码运行在openjdk1.8上。
也可以通过javap反编译查看,目前还不会看jvm 指令,以后再研究。

猜你喜欢

转载自lg-asus.iteye.com/blog/2393294