อะไรคือความแตกต่างระหว่าง "ข้อความ" และสตริงใหม่ ("ข้อความ")?


195

อะไรคือความแตกต่างระหว่างสองข้อความต่อไปนี้?

String s = "text";

String s = new String("text");

หัวข้อที่เกี่ยวข้อง: JEP 192: String Deduplication ใน G1
Basil Bourque

ทุกคนโปรดตอบกลับสิ่งนี้ String a = "Java"; String b = "Java"; System.out.println (a == b); true // but System.out.println ("a == b?" + a == b); // false ...
พลังงาน

ฉันไม่เข้าใจเมื่อฉันเพิ่มความคิดเห็น ("a == b?) => ผลลัพธ์ของฉันกลายเป็น FALSE เพราะเหตุใด
Energy

@Energy ผลลัพธ์เป็นfalseเพราะลำดับของการดำเนินการบอกว่าตัวดำเนินการ + ไปก่อนโดยทำการต่อ "a == b?" ด้วย a เพื่อสร้างสตริง "a == b? Java" จากนั้นนิพจน์"a==b?Java" == bประเมินว่าเป็นเท็จ
Allison B

@ AllisonB เข้าใจแล้วขอบคุณมาก!
พลังงาน

คำตอบ:


187

new String("text"); สร้างอินสแตนซ์ใหม่ของStringวัตถุที่ชัดเจนและอ้างอิงอย่างชัดเจน String s = "text";อาจนำอินสแตนซ์จากพูลคงที่สตริงกลับมาใช้ใหม่หากมีอยู่

คุณไม่ค่อยต้องการใช้ตัวnew String(anotherString)สร้าง จาก API:

String(String original): เริ่มต้นวัตถุที่สร้างขึ้นใหม่ Stringเพื่อให้มันแสดงถึงลำดับของตัวละครเช่นเดียวกับการโต้แย้ง กล่าวอีกนัยหนึ่งสตริงที่สร้างขึ้นใหม่คือสำเนาของสตริงอาร์กิวเมนต์ ยกเว้นว่าต้องการสำเนาต้นฉบับที่ชัดเจนการใช้ตัวสร้างนี้ไม่จำเป็นเนื่องจากสตริงไม่เปลี่ยนรูป

คำถามที่เกี่ยวข้อง


ความแตกต่างในการอ้างอิงหมายถึงอะไร

ตรวจสอบตัวอย่างข้อมูลต่อไปนี้:

    String s1 = "foobar";
    String s2 = "foobar";

    System.out.println(s1 == s2);      // true

    s2 = new String("foobar");
    System.out.println(s1 == s2);      // false
    System.out.println(s1.equals(s2)); // true

==ในสองประเภทอ้างอิงเป็นการเปรียบเทียบตัวตนของการอ้างอิง วัตถุที่สองที่ไม่จำเป็นต้องมีequals ==โดยปกติจะใช้ผิด==ประเภทการอ้างอิง เวลาส่วนใหญ่equalsจำเป็นต้องใช้แทน

อย่างไรก็ตามถ้าด้วยเหตุผลใดก็ตามที่คุณต้องการสร้างสองรายการequalsแต่ไม่ใช่==สตริงคุณสามารถใช้ตัวnew String(anotherString)สร้าง อย่างไรก็ตามจำเป็นต้องพูดอีกครั้งว่านี่เป็นเรื่องแปลกมากและไม่ค่อยมีเจตนา

อ้างอิง

ประเด็นที่เกี่ยวข้อง


3
ถ้าฉันเขียน: String s = new String ("abc"); และตอนนี้ฉันเขียน: String s = "abc"; สตริงจะ s = "abc"; สร้าง String ตามตัวอักษรใหม่ใน String Pool หรือไม่
Kaveesh Kanwal

ทำไมไม่มีใครตอบคำถามก่อนหน้า?
zeds

2
@KaveeshKanwal ไม่ตัวอักษรจะไม่ซ้ำซ้อน อย่างที่คุณเห็นมี 2 "abc"วิ มีเพียงหนึ่งในนั้นเท่านั้นที่จะไปที่ Pool String และอีกอันจะอ้างอิง จากนั้นมีสิ่งsที่จะเป็นวัตถุใหม่ที่เหมาะสม
Kayaman

1
@Kaveesh Kanwal - String s = new String ("abc") จะสร้างวัตถุ String ใหม่ที่มีค่า "abc" เท่านั้น และข้อความที่ 2 จะตรวจสอบว่ามีตัวอักษรสตริง "abc" อยู่ใน String Pool หรือไม่ ถ้ามีอยู่แล้วอ้างอิงถึงที่มีอยู่จะถูกส่งกลับและถ้าไม่แล้วตัวอักษรใหม่ ("abc") จะถูกสร้างขึ้นในสระว่ายน้ำสตริง หวังว่ามันจะช่วยแก้ปัญหาการค้นหาของคุณ !!
user968813

ไม่มี 'อาจ' เกี่ยวกับมัน คอมไพเลอร์ต้องพูสตริงตัวอักษร JLS 3.10.5
มาร์ควิสแห่ง Lorne

119

สตริงตัวอักษรจะไปเป็นสตริงค่าคงที่สระว่ายน้ำ

สแน็ปช็อตด้านล่างอาจช่วยให้คุณเข้าใจด้วยสายตาเพื่อจดจำเป็นเวลานานขึ้น

ป้อนคำอธิบายรูปภาพที่นี่


การสร้างวัตถุทีละบรรทัด:

String str1 = new String("java5");

การใช้สตริงตัวอักษร "java5" ในตัวสร้างค่าสตริงใหม่จะถูกเก็บไว้ในพูลคงที่ของสตริง การใช้ตัวดำเนินการใหม่วัตถุสตริงใหม่จะถูกสร้างขึ้นในฮีปที่มี "java5" เป็นค่า

String str2 = "java5"

การอ้างอิง "str2" ถูกชี้ไปที่ค่าที่เก็บไว้ในพูลคงที่ของสตริง

String str3 = new String(str2);

วัตถุสตริงใหม่ถูกสร้างขึ้นในฮีปที่มีค่าเหมือนกับการอ้างอิงโดย "str2"

String str4 = "java5";

การอ้างอิง "str4" ถูกชี้ไปที่ค่าที่เก็บไว้ในพูลคงที่ของสตริง

วัตถุทั้งหมด: ฮีป - 2, พูล - 1

อ่านเพิ่มเติมเกี่ยวกับชุมชน Oracle


1
คำตอบที่ดี .. แต่เราต้องรู้ว่าตอนนี้ฉัน giong เปลี่ยนค่าของ str1 = "java6" แล้วมันจะเปลี่ยนค่าของ str4?
CoronaPintu

2
ใช่ฉันตรวจสอบแล้วว่าจะไม่เปลี่ยนค่าของ str4
CoronaPintu

@Braj คุณสามารถให้เอกสารยืนยันคำตอบของคุณได้หรือไม่?
Basil Bourque

@Braj: ส่วนหัวของ 'Heap' & 'pool' ในตารางควรจะกลับกันไหม?
ราหุลคูรัป

ไม่ถูกต้อง. พูลคงที่ถูกสร้างขึ้นในเวลารวบรวมไม่ใช่เวลาดำเนินการ อย่าใช้การจัดรูปแบบคำพูดสำหรับข้อความที่ไม่ได้ยกมา
มาร์ควิสแห่ง Lorne

15

หนึ่งสร้างสตริงในString Constant Pool

String s = "text";

อีกสตริงหนึ่งสร้างสตริงในพูลคงที่ ( "text") และสตริงอื่นในพื้นที่ฮีปปกติ ( s) สตริงทั้งสองจะมีค่าเดียวกันนั่นคือ "ข้อความ"

String s = new String("text");

s จะหายไป (มีสิทธิ์สำหรับ GC) หากไม่ได้ใช้ในภายหลัง

สตริงตัวอักษรในทางกลับกันจะถูกนำมาใช้ใหม่ หากคุณใช้"text"ในหลาย ๆ สถานที่ในชั้นเรียนของคุณจริง ๆ แล้วมันจะเป็นหนึ่งในนั้นและมีเพียงหนึ่งสตริงเท่านั้น (เช่นการอ้างอิงหลายรายการไปยังสตริงเดียวกันในพูล)


เงื่อนไขในพูลคงที่จะไม่สูญหาย คุณหมายถึงว่า 's' หายไปหากไม่ได้ใช้ในภายหลัง
มาร์ควิสแห่ง Lorne

@EJP: ใช่ฉันหมายถึง "s" ขอบคุณที่สังเกต ฉันจะแก้ไขคำถาม

9

JLS

แนวคิดนี้เรียกว่า "การฝึกงาน" โดย JLS

ข้อความที่เกี่ยวข้องจากJLS 7 3.10.5 :

นอกจากนี้สตริงตัวอักษรมักจะหมายถึงอินสแตนซ์เดียวกันของคลาสสตริง นี่เป็นเพราะตัวอักษรสตริง - หรือโดยทั่วไปแล้วสตริงที่เป็นค่าของการแสดงออกอย่างต่อเนื่อง (§15.28) - เป็น "ฝึกงาน" เพื่อแบ่งปันกรณีที่ไม่ซ้ำกันโดยใช้วิธีการ String.intern

ตัวอย่าง 3.10.5-1 สตริงตัวอักษร

โปรแกรมประกอบด้วยชุดรวบรวม (§7.3):

package testPackage;
class Test {
    public static void main(String[] args) {
        String hello = "Hello", lo = "lo";
        System.out.print((hello == "Hello") + " ");
        System.out.print((Other.hello == hello) + " ");
        System.out.print((other.Other.hello == hello) + " ");
        System.out.print((hello == ("Hel"+"lo")) + " ");
        System.out.print((hello == ("Hel"+lo)) + " ");
        System.out.println(hello == ("Hel"+lo).intern());
    }
}
class Other { static String hello = "Hello"; }

และหน่วยรวบรวม:

package other;
public class Other { public static String hello = "Hello"; }

ผลิตผลลัพธ์:

true true true true false true

JVMs

JVMS 7 5.1 พูดว่า :

สตริงตัวอักษรคือการอ้างอิงถึงอินสแตนซ์ของคลาสสตริงและได้มาจากโครงสร้าง CONSTANT_String_info (§4.4.3) ในการเป็นตัวแทนไบนารีของชั้นเรียนหรืออินเตอร์เฟซ โครงสร้าง CONSTANT_String_info ให้ลำดับของจุดโค้ด Unicode ที่ประกอบเป็นตัวอักษรสตริง

ภาษาการเขียนโปรแกรม Java ต้องการตัวอักษรสตริงที่เหมือนกัน (นั่นคือตัวอักษรที่มีลำดับของจุดรหัสเดียวกัน) ต้องอ้างถึงอินสแตนซ์เดียวกันของคลาส String (JLS §3.10.5) นอกจากนี้ถ้าเมธอด String.intern ถูกเรียกบนสตริงใด ๆ ผลลัพธ์จะเป็นการอ้างอิงไปยังอินสแตนซ์ของคลาสเดียวกันที่จะถูกส่งคืนหากสตริงนั้นปรากฏเป็นตัวอักษร ดังนั้นการแสดงออกต่อไปนี้จะต้องมีค่าจริง:

("a" + "b" + "c").intern() == "abc"

เพื่อรับสตริงตัวอักษร Java Virtual Machine จะตรวจสอบลำดับของจุดโค้ดที่กำหนดโดยโครงสร้าง CONSTANT_String_info

  • หากก่อนหน้านี้มีการเรียกใช้เมธอด String.intern ในอินสแตนซ์ของคลาส String ที่มีลำดับของจุดโค้ด Unicode เหมือนกับที่กำหนดโดยโครงสร้าง

  • มิฉะนั้นอินสแตนซ์ใหม่ของคลาสสตริงจะถูกสร้างขึ้นซึ่งมีลำดับของจุดโค้ด Unicode ที่กำหนดโดยโครงสร้าง CONSTANT_String_info การอ้างอิงถึงอินสแตนซ์ของคลาสนั้นเป็นผลลัพธ์ของการสืบทอดสตริงตามตัวอักษร ในที่สุดวิธีการฝึกงานของอินสแตนซ์สตริงใหม่จะถูกเรียกใช้

bytecode

นอกจากนี้ยังแนะนำให้ดูที่การใช้ bytecode ใน OpenJDK 7

ถ้าเราแปลความหมาย:

public class StringPool {
    public static void main(String[] args) {
        String a = "abc";
        String b = "abc";
        String c = new String("abc");
        System.out.println(a);
        System.out.println(b);
        System.out.println(a == c);
    }
}

เรามีสระว่ายน้ำคงที่:

#2 = String             #32   // abc
[...]
#32 = Utf8               abc

และmain:

 0: ldc           #2          // String abc
 2: astore_1
 3: ldc           #2          // String abc
 5: astore_2
 6: new           #3          // class java/lang/String
 9: dup
10: ldc           #2          // String abc
12: invokespecial #4          // Method java/lang/String."<init>":(Ljava/lang/String;)V
15: astore_3
16: getstatic     #5          // Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: invokevirtual #6          // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: getstatic     #5          // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: invokevirtual #6          // Method java/io/PrintStream.println:(Ljava/lang/String;)V
30: getstatic     #5          // Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_1
34: aload_3
35: if_acmpne     42
38: iconst_1
39: goto          43
42: iconst_0
43: invokevirtual #7          // Method java/io/PrintStream.println:(Z)V

สังเกตว่า:

  • 0และ3: ldc #2โหลดค่าคงที่เดียวกัน(ตัวอักษร)
  • 12: อินสแตนซ์ของสตริงใหม่ถูกสร้างขึ้น (โดยมี#2อาร์กิวเมนต์เป็น)
  • 35: aและcถูกเปรียบเทียบเป็นวัตถุปกติด้วยif_acmpne

การเป็นตัวแทนของสตริงคงที่นั้นค่อนข้างน่าอัศจรรย์ใน bytecode:

  • มันมีโครงสร้างCONSTANT_String_infoเฉพาะซึ่งแตกต่างจากวัตถุปกติ (เช่นnew String)
  • struct ชี้ไปที่โครงสร้าง CONSTANT_Utf8_infoที่มีข้อมูล นั่นเป็นข้อมูลที่จำเป็นเพียงอย่างเดียวในการแสดงสตริง

และอ้าง JVMs ข้างต้นดูเหมือนจะบอกว่าเมื่อ UTF8 ldcชี้ไปที่จะเหมือนกันกรณีแล้วเหมือนจะถูกโหลดโดย

ฉันได้ทำการทดสอบที่คล้ายกันสำหรับสาขาและ:

  • static final String s = "abc"ชี้ไปที่ตารางค่าคงที่ผ่านแอตทริบิวต์ค่าคงที่
  • เขตข้อมูลที่ไม่ใช่ครั้งสุดท้ายไม่มีแอตทริบิวต์นั้น แต่ยังสามารถเริ่มต้นได้ด้วย ldc

สรุป : มีการสนับสนุน bytecode โดยตรงสำหรับสตริงพูลและการแสดงหน่วยความจำนั้นมีประสิทธิภาพ

โบนัส: เปรียบเทียบกับพูลจำนวนเต็มซึ่งไม่มีการสนับสนุนไบต์โดยตรง (เช่นไม่มีCONSTANT_String_infoอะนาล็อก)


2

@Braj: ฉันคิดว่าคุณได้พูดถึงวิธีอื่น ๆ โปรดแก้ไขฉันหากฉันผิด

การสร้างวัตถุทีละบรรทัด:

String str1 = new String ("java5")

   Pool- "java5" (1 Object)

   Heap - str1 => "java5" (1 Object)

String str2 = "java5"

  pool- str2 => "java5" (1 Object)

  heap - str1 => "java5" (1 Object)

String str3 = สตริงใหม่ (str2)

  pool- str2 => "java5" (1 Object)

  heap- str1 => "java5", str3 => "java5" (2 Objects)

String str4 = "java5"

  pool - str2 => str4 => "java5" (1 Object)

  heap - str1 => "java5", str3 => "java5" (2 Objects)

str1ไม่ได้มีส่วนร่วมในค่าของstr2หรือstr3หรือstr4ในทางใดทางหนึ่ง
มาร์ควิสแห่ง Lorne

1

คิดว่า"bla"การเป็นโรงงานเวทมนตร์เช่นStrings.createString("bla")(หลอก) โรงงานเก็บพูลของสตริงทั้งหมดที่สร้างด้วยวิธีนี้

ถ้ามันถูกเรียกใช้มันจะตรวจสอบว่ามีสตริงอยู่ในพูลแล้วด้วยค่านี้ ถ้าเป็นจริงมันส่งคืนวัตถุสตริงนี้ดังนั้นสตริงที่ได้รับด้วยวิธีนี้ย่อมเป็นวัตถุเดียวกัน

ถ้าไม่ใช่มันจะสร้างวัตถุสตริงใหม่ภายในบันทึกในพูลแล้วส่งคืนมัน ดังนั้นเมื่อค่าสตริงเดียวกันถูกเคียวรีในครั้งถัดไปมันจะส่งคืนอินสแตนซ์เดียวกัน

การสร้างการnew String("")แทนที่การทำงานนี้ด้วยตนเองโดยการข้ามสระตัวอักษรของสตริง ดังนั้นควรตรวจสอบความเสมอภาคโดยใช้equals()ซึ่งเปรียบเทียบลำดับอักขระแทนความเสมอภาคของการอ้างอิงวัตถุ


'โรงงานวิเศษ' ที่คุณอ้างถึงไม่มีอะไรมากไปกว่าคอมไพเลอร์ Java มันเป็นความผิดพลาดในการเขียนของกระบวนการนี้ราวกับว่ามันเกิดขึ้นที่รันไทม์
มาร์ควิสแห่ง Lorne

1

วิธีง่ายๆในการเข้าใจความแตกต่างอยู่ด้านล่าง: -

String s ="abc";
String s1= "abc";
String s2=new String("abc");

        if(s==s1){
            System.out.println("s==s1 is true");
        }else{
            System.out.println("s==s1 is false");
        }
        if(s==s2){
            System.out.println("s==s2 is true");
        }else{
            System.out.println("s==s2 is false");
        }

ผลลัพธ์คือ

s==s1 is true
s==s2 is false

ดังนั้น String ใหม่ () จะสร้างอินสแตนซ์ใหม่เสมอ


1

สตริงตัวอักษรใด ๆ ที่ถูกสร้างขึ้นภายในกลุ่มตัวอักษรสตริงและสระว่ายน้ำไม่อนุญาตให้ทำซ้ำ ดังนั้นหากวัตถุสตริงตั้งแต่สองตัวขึ้นไปถูกเริ่มต้นด้วยค่าตัวอักษรเดียวกันวัตถุทั้งหมดจะชี้ไปที่ตัวอักษรเดียวกัน

String obj1 = "abc";
String obj2 = "abc";

"obj1" และ "obj2" จะชี้ไปที่ตัวอักษรสตริงเดียวกันและพูลตัวอักษรสตริงจะมีตัวอักษร "abc" เพียงตัวเดียว

เมื่อเราสร้างวัตถุคลาส String โดยใช้คำหลักใหม่สตริงที่สร้างจึงถูกเก็บไว้ในหน่วยความจำฮีพ สตริงตัวอักษรใด ๆ ที่ถูกส่งผ่านเป็นพารามิเตอร์ไปยังตัวสร้างของคลาส String อย่างไรก็ตามจะถูกเก็บไว้ในสตริงพูล หากเราสร้างวัตถุหลายรายการโดยใช้ค่าเดียวกันกับผู้ประกอบการใหม่วัตถุใหม่จะถูกสร้างขึ้นในฮีปแต่ละครั้งเพราะผู้ประกอบการใหม่นี้ควรหลีกเลี่ยง

String obj1 = new String("abc");
String obj2 = new String("abc");

"obj1" และ "obj2" จะชี้ไปที่วัตถุสองชนิดที่แตกต่างกันในฮีปและพูลตัวอักษรสตริงจะมีตัวอักษร "abc" เพียงตัวเดียว

สิ่งที่น่าสังเกตเกี่ยวกับพฤติกรรมของสายอักขระก็คือสิ่งที่การกำหนดค่าใหม่หรือการต่อข้อมูลที่ทำบนสตริงสร้างวัตถุใหม่ในหน่วยความจำ

String str1 = "abc";
String str2 = "abc" + "def";
str1 = "xyz";
str2 = str1 + "ghi";

ในกรณีข้างต้น
บรรทัดที่ 1: ตัวอักษร "abc" จะถูกเก็บไว้ในกลุ่มสตริ
บรรทัดที่ 2: ตัวอักษร "abcdef" ได้รับการจัดเก็บไว้ในกลุ่มสตริ
บรรทัดที่ 3: ตัวอักษร "xyz" ใหม่ถูกเก็บไว้ในกลุ่มสตริและ "str1" เริ่มชี้ไปที่ตัวอักษรนี้
บรรทัดที่ 4: เนื่องจากค่าถูกสร้างขึ้นโดยผนวกต่อไปยังตัวแปรอื่นผลลัพธ์จะถูกเก็บไว้ในหน่วยความจำฮีปและตัวอักษรที่ถูกผนวก "ghi" จะถูกตรวจสอบว่ามีอยู่ในสตริงพูลและจะถูกสร้างขึ้นเนื่องจากไม่มีอยู่ใน กรณีข้างต้น


0

แม้ว่ามันจะดูเหมือนกันจากมุมมองของโปรแกรมเมอร์ แต่ก็มีผลกระทบต่อประสิทธิภาพการทำงานขนาดใหญ่ คุณต้องการใช้แบบฟอร์มแรกเกือบตลอดเวลา


0
String str = new String("hello")

มันจะตรวจสอบว่า String คงที่สระว่ายน้ำมีสตริง "hello" อยู่แล้ว? ถ้ามีอยู่มันจะไม่เพิ่มรายการใน String ค่าคงที่พูล หากไม่มีอยู่มันจะเพิ่มรายการใน String ค่าคงที่พูล

วัตถุจะถูกสร้างขึ้นในพื้นที่หน่วยความจำฮีปและstrจุดอ้างอิงไปยังวัตถุที่สร้างในตำแหน่งหน่วยความจำฮีป

ถ้าคุณต้องการstrอ้างอิงไปยังวัตถุจุดที่มีอยู่ในสระว่ายน้ำคงที่ String แล้วหนึ่งจะต้องโทรอย่างชัดเจนstr.intern();

String str = "world";

มันจะตรวจสอบว่า String คงที่สระว่ายน้ำมีสตริง "hello" อยู่แล้ว? ถ้ามีอยู่มันจะไม่เพิ่มรายการใน String ค่าคงที่พูล หากไม่มีอยู่มันจะเพิ่มรายการใน String ค่าคงที่พูล

ในทั้งสองกรณีข้างต้นstrจุดอ้างอิงไปยัง String "world"ปัจจุบันใน Constant pool


'มัน' เป็นคอมไพเลอร์ Java สตริงตัวอักษรสร้างรายการที่ไม่ซ้ำกันในสระว่ายน้ำคงที่ในเวลารวบรวม มันเป็นความผิดพลาดในการยกเลิกการสั่งการกระบวนการนี้ราวกับว่ามันเกิดขึ้นที่รันไทม์ ..
Marquis of Lorne

คุณช่วยอธิบายสิ่งที่ผิดในโพสต์นี้ได้อย่างชัดเจนหรือไม่?
Jayesh

มีอะไรผิดปกติในการโพสต์นี้คือตัวอักษรสตริงที่พูในเวลาที่บ่นตามที่ฉันพูดไปแล้ว ไม่ใช่เมื่อเรียกใช้งานโค้ดเช่นเดียวกับในคำตอบของคุณ
มาร์ควิสแห่ง Lorne

@EJP ฉันขอขอบคุณคำตอบของคุณ คุณช่วยชี้ให้เห็นบรรทัดที่แน่นอนซึ่งเป็นคำตอบที่ผิดได้ไหม ฉันเห็นคำตอบทั้งหมดข้างต้นเป็นแบบเดียวกับที่ฉันเขียน โปรดช่วยฉันต้องการแก้ไขความเข้าใจของฉัน ขอบคุณ
Jayesh

คุณได้เขียนเกี่ยวกับกระบวนการทั้งหมดราวกับว่ามันเกิดขึ้นเมื่อบรรทัดของรหัสจะถูกดำเนินการซึ่งตามที่ฉันได้บอกคุณซ้ำแล้วซ้ำอีกไม่ได้เป็นกรณี คุณไม่สามารถลดสิ่งเหล่านั้นทั้งหมดให้เป็น 'เส้นตรง' ที่ผิดในคำตอบของคุณ
มาร์ควิสแห่งลอร์น

0

เมื่อคุณเก็บสตริงเป็น

String string1 = "Hello";

โดยตรงจากนั้น JVM จะสร้างวัตถุ String พร้อมราคาที่กำหนดระหว่างบล็อกหน่วยความจำแยกต่างหากที่เรียกว่า String ค่าคงที่สระ

และเมื่อใดก็ตามที่เรามีแนวโน้มที่จะลองและผลิตสตริงอื่นเป็น

String string2 = "Hello";

JVM ตรวจสอบว่ามีวัตถุ String ใดที่มีราคาคงที่อยู่ภายในพูลคงที่ของ String หรือไม่ถ้าใช่แทนที่จะสร้างวัตถุใหม่ JVM กำหนดการอ้างอิงของวัตถุที่มีอยู่ให้กับตัวแปรใหม่

และเมื่อเราเก็บ String เป็น

String string = new String("Hello");

การใช้คีย์เวิร์ดใหม่จะมีการสร้างออบเจกต์ใหม่ที่มีราคาตามที่กำหนดไม่ว่าเนื้อหาของพูลคงที่ของ String จะเป็นเช่นไร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.