intern源码如下:
/**
* Returns a canonical representation for the string object.
* <p>
* A pool of strings, initially empty, is maintained privately by the
* class {@code String}.
* <p>
* 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}.
* <p>
* All literal strings and string-valued constant expressions are
* interned. String literals are defined in section 3.10.5 of the
* <cite>The Java™ Language Specification</cite>.
*
* @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();
这个方法是一个 native 的方法,注释为: 当调用 intern方法时,如果字符串常量池中已经包含一个等于此String对象的字符串(用equals(oject)方法确定),则返回池中的字符串(即字符串常量池的引用)。如果字符串常量池中没有此String,将此String对象添加到池中,并返回此String对象的引用。
归纳为:当调用 intern方法时,不管字符串常量池中有没有该String对象,最终都是返回此String在字符串常量池的引用。
例1:
String b = "11".intern();
String c = "11";
System.out.println(c==b);//true
解析:程序先去字符串常量池去找是否有“11”这个字符串,发现没有,就将“11”的字符串放入常量池,并且将其地址赋值给b。 由于“11”这个字符串在常量池里已经存在了,所以在执行 String c = "11"时,直接将“11”地址赋值给c。从而b与c都是指向同一地址的,因此 b==c值为true;
例2:
String a = new String("11");
String b = a.intern();
String c = "11";
System.out.println(a==b);//false
System.out.println(c==b);//true
解析:(假设程序执行时,常量池是空的)执行 new String(“11”)时分两步:其一,先去字符串常量池看是否有“11”,发现没有,则向字符串常量池放入“11”(如果“11”存在则不在放入)。其二,在java堆中创建一个String对象(内容为11),并将该对象的引用赋值给a。(注意此时的a指向的是堆内存String对象)
执行a.intern(),在字符串常量池中找到有“11”存在,则直接返回常量池中“11”的地址赋值给b,此时的b指向的是常量池中的“11”。由于字符串常量池中存在“11”,因此c=“11”,直接将常量池中“11”的地址赋值给c,即b与c指向的都是常量池中的“11”。
来源:CSDN
作者:hzh_shine
链接:https://blog.csdn.net/hzh_shine/article/details/104032335