最近看书看到了String的intern()方法,特此记录以下
首先,来看源码中的定义:
/**
* When the intern method is invoked, if the pool already contains a
* string equal to this {@code String} object as determined by
* the {@link #equals(Object)} method, then the string from the pool is
* returned. Otherwise, this {@code String} object is added to the
* pool and a reference to this {@code String} object is returned.
* <p>
* It follows that for any two strings {@code s} and {@code t},
* {@code s.intern() == t.intern()} is {@code true}
* if and only if {@code s.equals(t)} is {@code true}.
* @return a string that has the same contents as this string, but is
* guaranteed to be from a pool of unique strings.
*/
public native String intern();
上面的注释翻译过来大体意思为:当inter()方法被执行时,如果常量池中已经有一个与此String字符相等的对象的时候,则返回常量池中的String对象,否则将此String对象加入常量池中并返回。当且仅当s.equals(t)时s.intern() == t.intern()成立。
由于是native方法,看不见具体实现,这里就通过代码来测试,接下来来看如下代码:
public class StringTest {
private static final String SOURCE_STRING = "aaa";
@Test
public void testIntern() {
String src = new String("aaa");
String desc = new String("aaa");
System.out.println(desc == src);
String newSrc = src.intern();
String newDesc = desc.intern();
System.out.println(src == newSrc);
System.out.println(newDesc == newSrc);
System.out.println(newSrc == SOURCE_STRING);
System.out.println(newDesc == SOURCE_STRING);
}
}
运行结果:
false
false
true
true
true
接下来来逐条解释:
- src==desc这个为false很容易理解,src和desc都是指向的堆中的不同的两个对象,只是这两个对象的值都是aaa,但是他们有不同的内存地址,所以==符号做比对的话肯定为false;
- src==newSrc这一步中,src指向的是堆中值为aaa的这个对象;根据intern方法的定义可知,String newSrc = src.intern();这一步操作会检查常量池,其中已有值为aaa对象,即为SOURCE_STRING,之后将newStr的引用指向SOURCE_STRING,所以newSrc指向的是常量池中值为aaa的这个对象,所以src==newSrc结果为false;
- newDesc == newSrc;这个同2,都指向的是常量池中值为aaa的SOURCE_STRING对象,故结果相同;
- 后面两条是为了验证2所说,结果如运行结果。
我的博客:blog.scarlettbai.com