java中String对象的intern方法

首先,String实现了常量池技术

1. 看以下例子:
public class TestStringIntern {
	public static void main(String[] args) {
		String s0="StringIntern"; 
		String s1="StringIntern"; 
		String s2="String" + "Intern"; 
		System.out.println( s0==s1 ); 
		System.out.println( s0==s2 ); 
	}
}
结果是:
true
true

理解:因为s0和s1中的“StringIntern”都是字符串常量,他们在编译器就被确定了,“StringIntern”存在于常量池中,所以s0==s1为true;s2由两个常量连接而成,还是字符串常量,所以也为true。

2. 看一下列子
public class TestStringIntern {
	public static void main(String[] args) {
		String s0="StringIntern"; 
		String s1=new String("StringIntern"); 
		String s2="String" + new String("Intern"); 
		System.out.println( s0==s1 ); 
		System.out.println( s0==s2 ); 
		System.out.println( s1==s2 ); 
	}
}

结果:
false
false
false

理解:使用new String()创建的字符串不是常量,是在堆中生成的对象,不能在编译器就确定,所以不存在与常量池中。所以结果为false。

3. intern方法:存在于.class文件中的常量池,在运行期被jvm装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法,当一个String的实例str调用intern()方法是,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其引用;如果没有,则在常量池中增加一个Unicode等于该实例str的字符串并返回它的引用。看如下例子:
public class TestStringIntern {
	public static void main(String[] args) {
		String s0="StringIntern"; 
		String s1=new String("StringIntern"); 
		String s2=new String("StringIntern"); 
		System.out.println( s0==s1 ); 
		s1.intern(); //在常量池里扩展常量,发现已经存在了
		s2=s2.intern(); //把常量池中“StringIntern”的引用赋给s2 
		System.out.println( s0==s1); 
		System.out.println( s0==s1.intern() ); 
		System.out.println( s0==s2 ); 
	}
}

输出:

false

false

true

true


另外,如果使用new String()生成的对象str,调用intern()方法,则是在常量池中新添加一个值为str的字符串的常量,而不是复制地址。看一下例子:
public class TestStringIntern {
	public static void main(String[] args) {
		String s1=new String("StringIntern"); 
		String s2=s1.intern();//s1.intern()在常量池里新生成了一个常量,并将引用赋值给了s2
		System.out.println( s1==s1.intern() ); 
		System.out.println( s1+" "+s2 ); 
		System.out.println( s2==s1.intern() ); 
	}
}
输出:

false

StringIntern StringIntern

true

理解:在这个类中我们没有声名一个” StringIntern”常量,所以常量池中一开始是没有” StringIntern”的,当我们调用s1.intern()后就在常量池中新添加 了一个” StringIntern”常量,原来的不在常量池中的” StringIntern”仍然存在,也就不是“将自己的地址注册到常量池中”了。 s1==s1.intern()为false说明原来的“ StringIntern”仍然存在; s2现在为常量池中“ StringIntern”的地址,所以有s2==s1.intern()为true。 



你可能感兴趣的:(Java开发)