สตริงสามารถเริ่มต้นได้อย่างไรโดยใช้“”?


154

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


25
String เป็นคลาสวีไอพี " "เป็นสตริงอยู่แล้ว!
johnchen902

2
ไม่มีความหมายพิเศษ ฉันแค่ตั้งใจว่าสำคัญมาก นั่นคือjava.lang.Stringมีการปฏิบัติพิเศษของภาษา Java
johnchen902

16
ใครบอกว่าสตริงนั้นเป็น "คลาสเหมือน ๆ กัน"? เป็นคลาสที่พิเศษมากซึ่งแตกต่างจากที่อื่น เนื่องจากการคาดคะเนของคุณเป็นเท็จคำถามจึงไม่สามารถตอบได้จริงๆ
Eric Lippert

5
เพียงเพราะการคาดคะเนเป็นเท็จมันไม่ได้หมายความว่าคำถามไม่สามารถตอบได้ และคำตอบที่ถูกต้องมีคะแนนโหวต 197
Koray Tugay

คำตอบ:


293

Java String เป็นพิเศษ

นักออกแบบของ Java ตัดสินใจที่จะรักษาประเภทดั้งเดิมในภาษาเชิงวัตถุแทนที่จะทำให้ทุกอย่างเป็นวัตถุเพื่อปรับปรุงประสิทธิภาพของภาษา Primitives ถูกเก็บไว้ใน call stack ซึ่งต้องการพื้นที่เก็บข้อมูลน้อยกว่าและมีราคาถูกกว่าในการจัดการ ในทางกลับกันวัตถุจะถูกเก็บไว้ในกองโปรแกรมซึ่งต้องการการจัดการหน่วยความจำที่ซับซ้อนและพื้นที่เก็บข้อมูลมากขึ้น

ด้วยเหตุผลด้านประสิทธิภาพ String ของ Java ได้รับการออกแบบให้อยู่ระหว่างดั้งเดิมและคลาส

ตัวอย่างเช่น

String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object

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

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


72
โปรดทราบว่า "สระว่ายน้ำทั่วไป" มีมักจะเป็นส่วนหนึ่งของกอง
Joachim Sauer

3
@JoachimSauer ใช่ .. ด้วยผลประโยชน์เล็ก ๆ น้อย ๆ :) เพิ่มเข้าไปในโน้ตขอบคุณสำหรับความทรงจำ
Suresh Atta

2
ดังนั้นเร็วกว่าที่จะเขียน String s1 = "Hello"; กว่า String s2 = new String ("Hello") ;?
user2097804

28
ฉันจะเพิ่มเข้าไปในตัวอย่างของคุณ s1 == s2 == s3 แต่ s4! = s5
Alfredo Osorio

8
@AndrewJanke ในฮอตสปอตล่าสุด jvm (7), กลุ่มสตริงไม่ได้อยู่ในประเภทดัดและจาก Java 8 ไม่มีกลุ่มใบอนุญาตอีกต่อไป ...
assylias

50

Java ถือว่า String เป็นคลาสพิเศษคุณสามารถเริ่มต้นได้ทั้งสองวิธี

  1. กำหนดตัวอักษรโดยตรง

    String a = "adsasdf";
  2. เป็นวัตถุอื่น ๆ ที่ใช้คำหลักใหม่

    String a = new String("adsasdf");

คุณต้องระมัดระวังเป็นพิเศษเมื่อคุณต้องการเปรียบเทียบกับ==เครื่องหมาย:

String a = "asdf";
String b = "asdf";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True

String a = new String("asdf");
String b = new String("asdf");
System.out.println(a == b);  // False
System.out.println(a.equals(b)); // True

นั่นเป็นเพราะในกรณีแรกวัตถุ a และ b จะถูกเก็บไว้ในสิ่งที่เรียกว่าliteral poolและพวกเขาทั้งสองกำลังอ้างอิงวัตถุเดียวกันดังนั้นพวกเขาจะเท่ากันทั้งสองวิธี

แต่ในกรณีที่สอง a และ b อ้างอิงวัตถุต่าง ๆ เช่นเมื่อเราเริ่มต้นวัตถุอื่น ๆ ดังนั้นจึงไม่เท่ากันเมื่อเปรียบเทียบกับ==โอเปอเรเตอร์ในขณะที่ค่าเท่ากัน


18

String ได้รับการดูแลเป็นพิเศษใน JLS: มันเป็นหนึ่งในสองชนิดที่ไม่ใช่แบบดั้งเดิมที่ตัวอักษรที่มีอยู่ (อื่น ๆ ที่เป็นClass) *

จากJLS :

สตริงตัวอักษรเป็นการอ้างอิงถึงอินสแตนซ์ของคลาส `String [... ]

* ก็ยังมี "ประเภท null"ด้วย "null literal" nullแต่คนส่วนใหญ่ไม่คิดว่า "null type" เป็นประเภทที่เหมาะสม


1
ฉันก็ไม่ทราบว่า "ประเภท null" เป็นประเภทที่เหมาะสมใน Java ข้อมูลที่เป็นประโยชน์มากคุณควรเพิ่มขนาดตัวอักษร
Grijesh Chauhan

1
@GrijeshChauhan: ดี "ประเภท null" เป็นเพียงถ้อยคำที่ดีที่จะอนุญาตให้ใด ๆ ที่nullจะได้รับมอบหมายให้ตัวแปรประเภทการอ้างอิงใด ๆ มันไม่ใช่ประเภทที่น่าสนใจ
Joachim Sauer

15

มันเป็นคุณสมบัติของภาษาจาวา ตัวอักษรสตริงในซอร์สโค้ดจะได้รับการดูแลเป็นพิเศษ

spec ภาษาที่นี่เพียงแค่บอกว่าตัวอักษรสตริงเป็นStringประเภท


5

ข้อความภายในเครื่องหมายคำพูดคู่สร้างStringวัตถุที่แท้จริง

String myString = "Some text";

โค้ดด้านบนสร้างStringวัตถุโดยใช้เครื่องหมายคำพูดคู่


4

สตริงที่ใช้บ่อยในภาษาการเขียนโปรแกรม ตั้งแต่จาวาเป็นวัตถุเชิงสตริงเป็นวัตถุ เพื่อหลีกเลี่ยง String ใหม่ที่ยุ่งยาก ("someString"); คำสั่งทุกครั้งที่คุณต้องการวัตถุสตริง java ช่วยให้คุณเพียงแค่สร้างวัตถุสตริงโดยใช้สตริงตัวอักษร

แต่คุณควรคำนึงถึงความเสมอภาคของสตริง นี่คือการทดสอบ JUnit สั้น ๆ เพื่อแสดงให้เห็นว่าฉันหมายถึงอะไร

    @Test
    public void stringTest() {
       // a string literal and a string object created 
       // with the same literal are equal
       assertEquals("string", new String("string"));

       // two string literals are the same string object
       assertSame("string", "string"); 

       // a string literal is not the same object instance 
       // as a string object created with the same string literal
       assertFalse("string" == new String("string"));

       // java's String.intern() method gives you the same
       // string object reference for all strings that are equal.
       assertSame("string", new String("string").intern());
    }

หากคุณสามารถเริ่มต้นสตริงด้วยnew String(String src)เท่านั้นคุณจะไม่สามารถให้ตัวสร้างสตริงได้ตามตัวอักษร คุณจะต้องเริ่มต้นchar []และจากนั้นใช้ตัวString(char [] src)สร้างเพื่อสร้างสตริงหรือคุณจะต้องอ่านสตริงจากไฟล์
AJMansfield

นั่นไม่ถูกต้อง สตริงตัวอักษรเป็นเพียงลำดับตัวอักษรในไฟล์ต้นฉบับที่มาจากคำพูดคู่ Java สร้างอินสแตนซ์ของสตริงโดยอัตโนมัติโดยใช้ตัวอักษรนี้ ดังนั้นวัตถุที่แท้จริงและสตริงจะเท่ากัน แต่พวกเขาจะไม่เหมือนกัน Java อาจมีการใช้งานในลักษณะนี้ว่าคุณต้องใช้ String ใหม่ (""); เพื่อยกตัวอย่างวัตถุ String แต่สิ่งนี้จะทำให้ชีวิตของเรายากขึ้น ดังนั้นเมื่อคุณเขียน String ใหม่ ("สตริง") java สร้างวัตถุสตริงสำหรับตัวอักษร "สตริง" และส่งผ่านวัตถุสตริงนี้ไปที่ข้อ จำกัด ของสตริงใหม่
René Link

2

เพียงพูดถึง สตริงตัวอักษรเป็นการอ้างอิงถึงอินสแตนซ์ของคลาส String คุณสามารถเขียนโค้ดดังนี้:

 "ABC" .getBytes ();

 "A: B: C" .split ( ":");

 "愛" .codePointAt (0);

2

-สตริงเป็นชั้นในJava คุณมีความถูกต้องเกี่ยวกับมันดังนั้นเราจึงสามารถเริ่มต้นด้วยnewคำหลักได้เสมอ

-แต่เมื่อเราทำสิ่งที่ชอบ:

String s = "";

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

-ดังนั้นสตริงสามารถสร้างขึ้นโดยใช้new()และโดย""วิธีการ แต่อย่างหลังให้สตริงตัวอักษรที่อยู่ในกองแม้ในขณะที่ไม่มีการอ้างอิงถึงวัตถุสตริงนั้นเพราะมันมีการอ้างอิงจากสระว่ายน้ำตัวอักษรสตริง


2

Java ทำกระบวนการสองขั้นตอนสำหรับเรา

String str = "hello";

เทียบเท่ากับ

char data[] = {'h', 'e', 'l' , 'l', 'o'};
String str = new String(data);

เช่น [. NET] [1] มีสิ่งที่คล้ายกัน

String(Char[]) constructor

ทำ

String(char[] value)

เพิ่มการอ้างอิง: -


2
กระบวนการที่คุณอธิบายไม่ได้เป็นสิ่งที่ไม่จริง Java: เป็นคนอื่นได้ระบุไว้แล้ว"hello"เป็นตัวอักษรสตริงและจะถูกใส่ลงไปในสระว่ายน้ำอย่างต่อเนื่องโดยคอมไพเลอร์ดูJLS §3.10.5และJVMs §5.1
siegi

1

Java.lang.Stringไม่ใช่แค่ชั้นเรียน มันเป็นส่วนสำคัญของภาษาหลัก คอมไพเลอร์มีน้ำตาลซินแทคติคสำหรับมัน ยกตัวอย่างเช่นเป็นเหมือนย่อสำหรับ"" new String("")เมื่อเขียน""คอมไพเลอร์จะปรับสตริงที่เหมือนกันให้เหมาะสมกับอินสแตนซ์เดียวกันเพื่อประหยัดพื้นที่"a" + 5 == "a5" ==> true

คอมไพเลอร์มีน้ำตาลประโยคสำหรับสิ่งต่าง ๆ มากมายรวมถึงไม่ต้องทำกล่อง / unbox ระหว่างรุ่นวัตถุและชนิดดั้งเดิมไม่มีแม่หมายถึงวัตถุตัวสร้างเริ่มต้น ...


5
""new String("")ไม่ได้เป็นตัวย่อสำหรับ หากคุณใช้""สิ่งแรกที่จะทำคือค้นหาการจับคู่ในกลุ่มสตริงของ JVM และหากเป็นจริงจะส่งคืนสตริงนั้น โดยการใช้new String("")คุณจะสร้างสตริงใหม่เสมอแม้ว่าตัวสตริงจะมีอยู่แล้วในพูลสตริง (เพราะจะไม่ถูกเก็บไว้ในพูลสตริง)
g00glen00b

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