อาร์กิวเมนต์ทั้งหมดใน Java ถูกส่งผ่านโดยค่า เมื่อคุณผ่านStringไปยังฟังก์ชันค่าที่ผ่านไปคือการอ้างอิงไปยังวัตถุ String แต่คุณไม่สามารถแก้ไขการอ้างอิงนั้นและพื้นฐานวัตถุ String จะไม่เปลี่ยนรูป
งานที่ได้รับมอบหมาย
zText += foo;
เทียบเท่ากับ:
zText = new String(zText + "foo");
นั่นคือมัน (ภายในเครื่อง) กำหนดพารามิเตอร์zTextใหม่เป็นการอ้างอิงใหม่ซึ่งชี้ไปยังตำแหน่งหน่วยความจำใหม่ซึ่งเป็นเนื้อหาใหม่Stringที่มีเนื้อหาดั้งเดิมของzTextพร้อมกับ"foo"ผนวก
วัตถุต้นฉบับไม่ได้ถูกแก้ไขและmain()ตัวแปรท้องถิ่นของวิธีการzTextยังคงชี้ไปที่สตริงเดิม (ว่าง)
class StringFiller {
static void fillString(String zText) {
zText += "foo";
System.out.println("Local value: " + zText);
}
public static void main(String[] args) {
String zText = "";
System.out.println("Original value: " + zText);
fillString(zText);
System.out.println("Final value: " + zText);
}
}
พิมพ์:
Original value:
Local value: foo
Final value:
หากคุณต้องการแก้ไขสตริงคุณสามารถใช้งานได้ตามที่ระบุไว้StringBuilderหรืออย่างอื่นบางคอนเทนเนอร์ (อาเรย์หรือAtomicReferenceคลาสคอนเทนเนอร์แบบกำหนดเอง) ที่ให้คุณเพิ่มระดับการชี้ทางอ้อม หรือเพียงแค่คืนค่าใหม่และกำหนด:
class StringFiller2 {
static String fillString(String zText) {
zText += "foo";
System.out.println("Local value: " + zText);
return zText;
}
public static void main(String[] args) {
String zText = "";
System.out.println("Original value: " + zText);
zText = fillString(zText);
System.out.println("Final value: " + zText);
}
}
พิมพ์:
Original value:
Local value: foo
Final value: foo
นี่อาจเป็นคำตอบที่เหมือนกับ Java ที่สุดในกรณีทั่วไป - ดูรายการJava ที่มีประสิทธิภาพ "Favor immutability"
ตามที่ระบุไว้ แต่StringBuilderมักจะให้ประสิทธิภาพที่ดีขึ้น - StringBuilderถ้าคุณมีจำนวนมากของการผนวกที่จะทำโดยเฉพาะอย่างยิ่งภายในห่วงการใช้งาน
แต่พยายามที่จะผ่านสิ่งที่ไม่เปลี่ยนรูปStringsแทนการเปลี่ยนแปลงStringBuildersหากคุณทำได้ - รหัสของคุณจะอ่านง่ายขึ้นและบำรุงรักษาได้มากขึ้น พิจารณาสร้างพารามิเตอร์ของคุณfinalและกำหนดค่า IDE ของคุณเพื่อเตือนคุณเมื่อคุณกำหนดพารามิเตอร์เมธอดให้เป็นค่าใหม่