Java String intern()方法
阿新 • • 發佈:2019-02-13
引言
在 JAVA 語言中有8中基本型別和一種比較特殊的型別String
。這些型別為了使他們在執行過程中速度更快,更節省記憶體,都提供了一種常量池的概念。常量池就類似一個JAVA系統級別提供的快取。
8種基本型別的常量池都是系統協調的,String
型別的常量池比較特殊。它的主要使用方法有兩種:
-
直接使用雙引號宣告出來的
String
物件會直接儲存在常量池中。 -
如果不是用雙引號宣告的
String
物件,可以使用String
提供的intern
方法。intern 方法會從字串常量池中查詢當前字串是否存在,若不存在就會將當前字串放入常量池中
接下來我們主要來談一下String#intern
一, intern 的實現原理
首先深入看一下它的實現原理。
1,JAVA 程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
/**
*
Returns a canonical representation for the string object.
*
<p>
*
A pool of strings, initially empty, is maintained privately by the *
class <code>String</code>.
*
<p>
*
When the intern method is invoked, if the pool already contains a
*
string equal to this <code>String</code> object as determined by
*
the {@link #equals(Object)} method, then the string from the pool is
*
returned. Otherwise, this <code>String</code> object is added to the *
pool and a reference to this <code>String</code> object is returned.
*
<p>
*
It follows that for any two strings <code>s</code> and <code>t</code>,
*
<code>s.intern() == t.intern()</code> is <code>true</code>
*
if and only if <code>s.equals(t)</code> is <code>true</code>.
*
<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();
|
String#intern
方法中看到,這個方法是一個 native 的方法,但註釋寫的非常明瞭。“如果常量池中存在當前字串, 就會直接返回當前字串.
如果常量池中沒有此字串, 會將此字串放入常量池中後, 再返回”。
2,native 程式碼
在 jdk7後,oracle 接管了 JAVA 的原始碼後就不對外開放了,根據 jdk 的主要開發人員宣告 openJdk7 和 jdk7 使用的是同一分主程式碼,只是分支程式碼會有些許的變動。所以可以直接跟蹤 openJdk7 的原始碼來探究 intern 的實現。
native實現程式碼:
\openjdk7\jdk\src\share\native\java\lang\String.c
1 2 3 4 |
Java_java_lang_String_intern(JNIEnv
*env, jobject this )
{
return
JVM_InternString(env, this );
}
|
\openjdk7\hotspot\src\share\vm\prims\jvm.h