1. ประการแรก String ไม่ได้อยู่ในประเภทข้อมูลพื้นฐาน 8 ชนิด
เนื่องจากค่าเริ่มต้นของวัตถุเป็น null ค่าเริ่มต้นของ String จึงเป็น null เช่นกัน แต่เป็นวัตถุพิเศษและมีคุณสมบัติบางอย่างที่วัตถุอื่นไม่มี
2. new String() และ new String("") ทั้งคู่ประกาศสตริงว่างใหม่ ซึ่งเป็นสตริงว่างและไม่ใช่ null
3. สตริง str="kvill";
ความแตกต่างระหว่าง String str=new String ("kvill");:
ในที่นี้ เราจะไม่พูดถึงฮีปหรือสแต็ก แต่เพียงแนะนำแนวคิดง่ายๆ ของพูลคงที่
พูลคงที่หมายถึงพูลที่กำหนด ณ เวลาคอมไพล์และจัดเก็บไว้ในพูลที่คอมไพล์ ข้อมูลบางส่วนในไฟล์คลาส ประกอบด้วยค่าคงที่ในคลาส วิธีการ อินเทอร์เฟซ ฯลฯ รวมถึงค่าคงที่สตริง
ดูตัวอย่างที่ 1:
คัดลอกรหัสรหัส ดังต่อไปนี้:
สตริง s0="kvill";
สตริง s1="kvill";
สตริง s2="kv" + "ป่วย";
System.out.println( s0==s1 );
System.out.println( s0==s2 );
ผลลัพธ์คือ:
จริง
จริง
อันดับแรก เราต้องรู้ว่า Java จะตรวจสอบให้แน่ใจว่ามีสำเนาของค่าคงที่สตริงเพียงสำเนาเดียวเท่านั้น
เนื่องจาก "kvill" ใน s0 และ s1 ในตัวอย่างเป็นค่าคงที่สตริงทั้งคู่ จึงถูกกำหนด ณ เวลาคอมไพล์ ดังนั้น s0==s1 จึงเป็นจริง และ "kv" และ "ill" ก็เป็นค่าคงที่สตริงเช่นกัน เมื่อสตริงถูกต่อกันด้วย ค่าคงที่สตริงหลายค่า จะต้องเป็นค่าคงที่สตริง ดังนั้น s2 จึงถูกแยกวิเคราะห์เป็นค่าคงที่สตริง ณ เวลาคอมไพล์ด้วย ดังนั้น s2 จึงเป็นหนึ่งใน "kvill" ใน Quote ของพูลค่าคงที่ด้วย
ดังนั้นเราจึงได้ s0==s1==s2;
สตริงที่สร้างด้วย new String() ไม่ใช่ค่าคงที่และไม่สามารถระบุได้ในขณะคอมไพล์ ดังนั้นสตริงที่สร้างด้วย String() ใหม่จะไม่ถูกใส่ลงในพูลค่าคงที่ เนื่องจากสตริงเหล่านี้มีพื้นที่ที่อยู่ของตัวเอง
ดูตัวอย่างที่ 2:
คัดลอกรหัสรหัส ดังต่อไปนี้:
สตริง s0="kvill";
สตริง s1=สตริงใหม่("kvill");
สตริง s2="kv" + สตริงใหม่ ("ป่วย");
System.out.println( s0==s1 );
System.out.println( s0==s2 );
System.out.println( s1==s2 );
ผลลัพธ์คือ:
เท็จ
เท็จ
เท็จ
ในตัวอย่างที่ 2 s0 ยังคงเป็นแอปพลิเคชันของ "kvill" ในพูลคงที่ เนื่องจากไม่สามารถระบุ s1 ได้ในขณะรวบรวม จึงเป็นการอ้างอิงถึงวัตถุใหม่ "kvill" ที่สร้างขึ้นเมื่อรันไทม์ เนื่องจาก s2 มีครึ่งหลังของ newString ("ป่วย") ก็คือ ไม่สามารถระบุได้ในขณะคอมไพล์ ดังนั้นจึงเป็นแอปพลิเคชันของวัตถุที่สร้างขึ้นใหม่ "kvill" หากคุณเข้าใจสิ่งนี้ คุณจะรู้ว่าเหตุใดจึงได้รับผลลัพธ์นี้
4. String.ฝึกงาน():
ฉันขอเพิ่มอีกประเด็นหนึ่ง: มีอยู่ใน พูลคงที่ในไฟล์คลาสถูกโหลดโดย JVM ระหว่างรันไทม์และสามารถขยายได้ เมธอด intern() ของ String เป็นวิธีการขยายพูลค่าคงที่ เมื่อ String instance str เรียกเมธอด intern() แล้ว Java จะตรวจสอบว่ามีค่าคงที่สตริงที่มี Unicode เดียวกันในพูลค่าคงที่หรือไม่ หากเป็นเช่นนั้น ก็จะส่งคืน การอ้างอิง ถ้าไม่ ให้เพิ่มสตริง Unicode เท่ากับ str ในพูลค่าคงที่และส่งคืนการอ้างอิง โดยดูจากตัวอย่างที่ 3 ตัวอย่างที่ 3:
คัดลอกรหัสรหัส ดังต่อไปนี้:
สตริง s0= "kvill";
สตริง s1=สตริงใหม่("kvill");
สตริง s2=สตริงใหม่("kvill");
System.out.println( s0==s1 );
System.out.println( "**********" );
s1.ฝึกงาน();
s2=s2.intern(); //กำหนดการอ้างอิงของ "kvill" ในพูลคงที่ให้กับ s2
System.out.println(s0==s1);
System.out.println( s0==s1.intern() );
System.out.println( s0==s2 );
ผลลัพธ์คือ:
เท็จ
-
false //แม้ว่า s1.intern() จะถูกดำเนินการ แต่ค่าที่ส่งคืนไม่ได้ถูกกำหนดให้กับ s1
จริง //บ่งชี้ว่า s1.intern() ส่งคืนการอ้างอิงถึง "kvill" ในพูลคงที่
จริง
สุดท้ายนี้ ผมขอขจัดความเข้าใจผิดอีกประการหนึ่ง:
มีคนบอกว่า "ใช้เมธอด String.intern() เพื่อบันทึกคลาส String ลงในตาราง String ส่วนกลาง หากมีสตริง Unicode ที่มีค่าเดียวกันอยู่ในตารางนี้อยู่แล้ว เมธอดนี้จะส่งคืนสตริงที่อยู่ในตารางอยู่แล้ว หากไม่มีสตริงที่มีค่าเท่ากันในตาราง ให้ลงทะเบียนที่อยู่ของคุณเองในตาราง "ถ้าฉันเข้าใจตาราง Global String ที่เขาบอกว่าเป็นค่าคงที่ ประโยคสุดท้ายของเขาคือ "ถ้ามีสตริงใน ตาราง หากไม่มีสตริงที่มีค่าเท่ากัน การลงทะเบียนที่อยู่ของคุณเองในตารางถือเป็นความผิด:
ดูตัวอย่างที่ 4:
คัดลอกรหัสรหัส ดังต่อไปนี้:
สตริง s1=สตริงใหม่("kvill");
สตริง s2=s1.intern();
System.out.println( s1==s1.intern() );
System.out.println( s1+" "+s2 );
System.out.println( s2==s1.intern() );
ผลลัพธ์คือ:
เท็จ
ควิลล์ ควิลล์
จริง
ในคลาสนี้ เราไม่ได้ประกาศค่าคงที่ "kvill" ดังนั้นจึงไม่มี "kvill" ในกลุ่มค่าคงที่ในตอนเริ่มต้น เมื่อเราเรียก s1.intern() ค่าคงที่ "kvill" ใหม่จะถูกเพิ่มเข้าไปในพูลค่าคงที่ ปรากฎว่า "kvill" ที่ไม่ได้อยู่ในพูลคงที่ยังคงมีอยู่ ซึ่งหมายความว่าไม่ได้ "ลงทะเบียนที่อยู่ของตัวเองในพูลคงที่"
s1==s1.intern() เป็นเท็จ ซึ่งบ่งชี้ว่า "kvill" ดั้งเดิมยังคงอยู่
ตอนนี้ s2 เป็นที่อยู่ของ "kvill" ในพูลคงที่ ดังนั้น s2==s1.intern() จึงเป็นจริง
5. เกี่ยวกับเท่ากับ() และ ==:
สำหรับ String นี่เป็นเพียงการเปรียบเทียบว่าลำดับ Unicode ของสองสตริงเท่ากันหรือไม่ และส่งคืนค่าจริงหากเท่ากัน และ == คือการเปรียบเทียบว่าที่อยู่ของทั้งสองสตริงเหมือนกันหรือไม่ กล่าวคือ ไม่ว่าจะเป็นการอ้างอิงหรือไม่ ให้เป็นสายเดียวกัน
6. เกี่ยวกับ String ไม่สามารถเปลี่ยนรูปได้
มีเรื่องให้พูดมากมายเกี่ยวกับเรื่องนี้ ตราบใดที่คุณรู้ว่าอินสแตนซ์ String จะไม่เปลี่ยนแปลงเมื่อถูกสร้างขึ้น เช่น: String str="kv"+"ill"+" "+"ans";
มีค่าคงที่สตริง 4 ค่า ขั้นแรก "kv" และ "ill" สร้าง "kvill" ซึ่งถูกเก็บไว้ในหน่วยความจำ จากนั้น "kvill" จะถูกรวมเข้ากับ " " เพื่อสร้าง "kvill" และถูกเก็บไว้ในหน่วยความจำในที่สุด ถูกรวมเข้ากับ "kvill ans" เพื่อสร้าง "kvill ans" และกำหนดที่อยู่ของสตริงนี้ให้กับ str เนื่องจาก "ความไม่เปลี่ยนรูป" ของ String จะสร้างตัวแปรชั่วคราวจำนวนมาก ซึ่งเป็นสาเหตุที่แนะนำให้ใช้ StringBuffer เนื่องจาก StringBuffer เปลี่ยนแปลงได้