ช่วยแบ่งมันออกเป็นบางส่วน
String s1 = "hello";
คำสั่งนี้สร้างสตริงที่ประกอบด้วยhelloและใช้พื้นที่ในหน่วยความจำเช่นในConstant String Poolและกำหนดให้กับวัตถุอ้างอิงs1
String s2 = s1;
คำสั่งนี้กำหนดสตริงเดียวกันสวัสดีให้กับการอ้างอิงใหม่s2
__________
| |
s1 ---->| hello |<----- s2
|__________|
การอ้างอิงทั้งสองชี้ไปที่สตริงเดียวกันดังนั้นให้ส่งออกค่าเดียวกันดังนี้
out.println(s1); // o/p: hello
out.println(s2); // o/p: hello
แม้ว่าStringคือไม่เปลี่ยนรูปได้รับมอบหมายสามารถเป็นไปได้เพื่อให้s1ตอนนี้จะหมายถึงค่าใหม่สแต็ค
s1 = "stack";
__________
| |
s1 ---->| stack |
|__________|
แต่สิ่งที่เกี่ยวกับวัตถุs2ซึ่งชี้ไปที่สวัสดีมันจะเป็นอย่างที่มันเป็น
__________
| |
s2 ---->| hello |
|__________|
out.println(s1); // o/p: stack
out.println(s2); // o/p: hello
เนื่องจาก String เป็นJava Virtual Machine ที่ไม่เปลี่ยนรูปแบบจะไม่อนุญาตให้เราแก้ไข string s1ด้วยวิธีการ มันจะสร้างวัตถุ String ใหม่ทั้งหมดในกลุ่มดังนี้
s1.concat(" overflow");
___________________
| |
s1.concat ----> | stack overflow |
|___________________|
out.println(s1); // o/p: stack
out.println(s2); // o/p: hello
out.println(s1.concat); // o/p: stack overflow
หมายเหตุถ้า String จะไม่แน่นอนจากนั้นจะได้รับการออก
out.println(s1); // o/p: stack overflow
ตอนนี้คุณอาจประหลาดใจว่าทำไม String ถึงมีวิธีการเช่นconcat ()เพื่อแก้ไข ตัวอย่างต่อไปนี้จะล้างความสับสนของคุณ
s1 = s1.concat(" overflow");
ที่นี่เรากำลังกำหนดค่าที่แก้ไขของสตริงกลับไปที่การอ้างอิงs1
___________________
| |
s1 ---->| stack overflow |
|___________________|
out.println(s1); // o/p: stack overflow
out.println(s2); // o/p: hello
นั่นเป็นเหตุผลที่ Java ตัดสินใจให้ String เป็นคลาสสุดท้ายมิฉะนั้นใคร ๆ ก็สามารถแก้ไขและเปลี่ยนแปลงค่าของสตริงได้ หวังว่านี่จะช่วยได้นิดหน่อย