在Java中,字串作為String類別的物件儲存在記憶體中。
當為任何Java程式分配記憶體時,JVM(Java虛擬機器)將分配的記憶體分為兩部分。一部分是棧,另一部分是堆。在堆內存中,java分配了一些內存,特別是對於字面量,這塊內存被稱為字串常數池(SCP)。 SCP 是堆內預先定義的區域。字串池有助於為 Java 運行時節省大量空間。 String 類別使用 SCP 來儲存唯一的字串文字。
在堆疊記憶體中,儲存變數或變數參考或物件的參考。
堆記憶體中儲存了所有動態分配的物件。為了給物件分配內存,我們使用 new 關鍵字。
建立字串物件有兩種方法。
字串 str1 = “MyString”;
每當我們建立字串文字時,JVM 首先檢查該字串文字是否已存在於字串常數池中。如果不可用,它將在 SCP 中建立一個新的字串文字。
上圖中,str1指向SCP中的「MyString」。以下是處理新建立的字串文字的方式。
String str2 = new String(“MyString”); //使用new關鍵字實例化字串類別
當使用 new 關鍵字建立字串物件時,它將建立兩個物件。一個在 SCP 中,另一個在堆中,引用變數儲存在堆疊中。
我們已經使用
建立了文字“MyString”字串 str1 = “MyString”;
由於 SCP 中不能有重複項,因此 JVM 不會在 SCP 中再建立一個對象,而是傳回對堆疊中變數 str3 的現有引用,並在堆中建立一個物件。 Str3 將指向堆中的物件“MyString”,但不指向 SCP 中的物件。
以下是如何為字串物件分配記憶體的不同情況。
情況1:上面定義的字串物件如何儲存在記憶體中。
公有類別字串儲存概念
{
public static void main(String[] args)
{
字串 str1 = “MyString”;
String str2 = new String(“MyString”);
System.out.println(str1 == str2); //輸出:False
System.out.println(str1.equals(str2)); //輸出:True
}
}
當我們使用「==」運算子來比較 str1 和 str2 時,它會傳回 false。眾所周知,「==」運算子會比較它們的實體位址。在我們的範例中,str1 指向 SCP 中的對象,str2 指向堆中的對象。所以它回傳 false。
但在 str1.equals(str2) 的情況下,正如我們所知,「equals」函數會檢查 str1 和 str3 中的各個字元是否具有相同的儲存值,並傳回 true。
情況 2:另一個字串文字
字串 str3 = “MyString”;
str1 和 str3 都將指向 SCP 中的相同字串文字。
公有類別字串儲存概念
{
public static void main(String[] args)
{
字串 str1 = “MyString”;
字串 str3 = “MyString”;
System.out.println(str1 == str2); //輸出:True
System.out.println(str1.equals(str2)); //輸出:True
}
}
s1 == s3 傳回 true,因為「==」運算子比較它們的實體位址,但不比較內容。
s1.equals(s3) 傳回 true,「equals」 函數檢查兩個引用變數中的單一字元。
情況 3:使用新關鍵字建立另一個字串物件
String str4 = new String(“NewString”);
在這種情況下,JVM會在SCP中檢查該字串,但找不到值為「NewString」的字串對象,因此會建立兩個對象,一個在SCP中,另一個在Heap中,引用變數str4將儲存在堆疊。 Str4 將擁有對堆中物件的引用。
情況 4:建立另一個字串文字。
字串 str5 = “NewString”;
在這種情況下,JVM 會在SCP 中檢查該文字是否已經可用,這裡「NewString」已經存在於SCP 中,因此JVM 不會在SCP 中建立重複項,而是傳回變數str5 的引用。
情況 5:將一個字串分配給另一個字串
String str4 = new String(“NewString”);
字串 str6 = str4; //賦值
這裡str6和str4會指向Heap中的同一個對象,不會擦除str4中的值。
公有類別字串儲存概念
{
public static void main(String[] args)
{
String str4 = new String(“NewString”);
字串 str6 = str4;
System.out.println(str4 == str6); //輸出:true
}
}
JVM會將堆中「NewString」的引用賦予變數str6。這就是 str4 == str6 傳回 true 的原因。
總而言之,使用字串文字和「new」運算子建立字串物件有其優點和缺點。
透過使用字串文字,我們可以透過不建立重複項來提高記憶體效率。 JVM 會建立一個唯一的對象,並且該字串永遠保留在 SCP 中。這樣做的缺點是字串池的大小是固定的,有時會變滿。
但透過使用 new 關鍵字,它創建了兩個對象,一個在 SCP 中,另一個在堆中。在堆中,如果我們不需要該對象,垃圾收集器將刪除該對像以騰出空間。但這樣做的缺點是,使用「new」運算符,JVM 總是必須建立一個新對象,這對 JVM 來說是一個重載。
以上是Java中字串的記憶體分配的詳細內容。更多資訊請關注PHP中文網其他相關文章!