Java中String类的intern()方法深入理解。

来源:互联网 发布:跨域调用js方法 编辑:程序博客网 时间:2024/04/28 18:05

我们很少用到intern()这个方法,那么这个方法有什么用呢?

先看一段代码:

String s1 = new String("RD");// 指向堆对象引用String s2 = s1.intern(); // 向常量池添加s1 并且S2引用常量池String s3 = "RD";System.out.println(s1 == s2);System.out.println(s3 == s2);System.out.println(s3 == s1);

这一段的输出结果为:

falsetruefalse

通过注释我们理解到,intern()方法是把对象的引用添加到常量池(jdk1.7之后运行时常量池被移动到了Java堆里(Java Heap))。

所以上段代码是吧字符串"RD"放到常量池中一份,并返回引用指向s2。s3这种直接赋值的声明方法,是看常量池中存不存在"RD",若不存在,在常量池中创建并引用,若存在,直接引用。所以第第二行输出为true。

因为s1的引用是java堆中的对象,所以第一行和第三行输出false。


再看一段代码:

String s0 = "RD";String s1 = new String("RD");String s2 = s1.intern();String s3 = "RD";System.out.println(s1 == s2);System.out.println(s3 == s2);System.out.println(s3 == s1);System.out.println(s0 == s2);


这一段输出结果为:

falsetruefalsetrue


这段代码第四行输出了true,可见intern()方法再放入常量池时会判断常量池中是否已经存在"RD",如果存在,直接返回常量池中"RD"的引用。



再看下边三段代码:

代码1:

String s1 = new String("RD");String s2 = s1.intern();System.out.println(s2 == s1);
输出为:
false

代码2:

String s1 = new String("RD") + new String("_Lee");String s2 = s1.intern();System.out.println(s2 == s1);

输出为:
true

代码3:
String s0 = "RD_Lee";String s1 = new String("RD") + new String("_Lee");String s2 = s1.intern();System.out.println(s2 == s1);
输出为:
false

通过1,2,3段代码对比我们发现,当一个组合声明的字符串时,intern()方法不仅把s1的字符串放进常量池中并返回引用给s2,且同时把引用返回给了s1;所以推测intern还会把组合字符串的引用从堆中指到常量池,为了验证此想法,我们试验如下代码。

代码1:

String s1 = new String("RD") + new String("_Lee");s1.intern();String s2 = "RD_Lee";System.out.println(s2 == s1);
其返回值为:
true
2:
String s1 = new String("RD") + new String("_Lee");String s2 = "RD_Lee";System.out.println(s2 == s1);
其返回值为:
false
3:

String s1 = new String("RD");s1.intern();String s2 = "RD";System.out.println(s2 == s1);
其返回值为:
false
通过代码1和代码3我们可以了解到,intern()可以将通过"+"声明的这种字符串从常量池中创建,并返回引用给自身。对单独的new的字符串不可以。

通过代码1和代码2我们了解到,确实是intern()方法起了作用,并不是这种“+”创建方式会直接在常量池中创建字符串。


测试版本:jdk1.8.



欢迎指正错误~