หยุดการมอบหมายตัวแปรใหม่
แม้ว่าคำตอบเหล่านี้น่าสนใจ แต่ฉันไม่ได้อ่านคำตอบสั้น ๆ ง่ายๆ:
ใช้คำสำคัญสุดท้ายเมื่อคุณต้องการให้คอมไพเลอร์เพื่อป้องกันไม่ให้ตัวแปรถูกกำหนดใหม่ให้กับวัตถุอื่น
ไม่ว่าจะเป็นตัวแปรที่เป็นตัวแปรสแตติกตัวแปรสมาชิกตัวแปรโลคัลหรือตัวแปรอาร์กิวเมนต์ / พารามิเตอร์ผลจะเหมือนกันทั้งหมด
ตัวอย่าง
เรามาดูผลของการกระทำกัน
พิจารณาวิธีการง่ายๆนี้ซึ่งทั้งสองตัวแปร ( หาเรื่องและx ) สามารถกำหนดวัตถุที่แตกต่างกันได้อีกครั้ง
// Example use of this method:
// this.doSomething( "tiger" );
void doSomething( String arg ) {
String x = arg; // Both variables now point to the same String object.
x = "elephant"; // This variable now points to a different String object.
arg = "giraffe"; // Ditto. Now neither variable points to the original passed String.
}
ทำเครื่องหมายตัวแปรท้องถิ่นเป็นครั้งสุดท้าย ซึ่งส่งผลให้เกิดข้อผิดพลาดของคอมไพเลอร์
void doSomething( String arg ) {
final String x = arg; // Mark variable as 'final'.
x = "elephant"; // Compiler error: The final local variable x cannot be assigned.
arg = "giraffe";
}
แต่ขอให้ทำเครื่องหมายตัวแปรพารามิเตอร์เป็นครั้งสุดท้าย ซึ่งจะส่งผลให้เกิดข้อผิดพลาดของคอมไพเลอร์ด้วย
void doSomething( final String arg ) { // Mark argument as 'final'.
String x = arg;
x = "elephant";
arg = "giraffe"; // Compiler error: The passed argument variable arg cannot be re-assigned to another object.
}
นิทานสอนใจ:
ถ้าคุณต้องการเพื่อให้แน่ใจว่าตัวแปรเสมอจุดไปที่วัตถุเดียวกันทำเครื่องหมายตัวแปรสุดท้าย
ไม่ต้องกำหนดอาร์กิวเมนต์ใหม่
ในฐานะที่เป็นแนวปฏิบัติในการเขียนโปรแกรมที่ดี (ในภาษาใด ๆ ) คุณไม่ควรกำหนดตัวแปรพารามิเตอร์ / อาร์กิวเมนต์ให้กับวัตถุอื่นนอกเหนือจากวัตถุที่ส่งผ่านโดยวิธีการโทร arg =
ในตัวอย่างข้างต้นหนึ่งไม่ควรเขียนเส้น เนื่องจากมนุษย์ทำผิดพลาดและโปรแกรมเมอร์เป็นมนุษย์เราจึงขอให้ผู้แปลช่วยเรา ทำเครื่องหมายทุกตัวแปรพารามิเตอร์ / อาร์กิวเมนต์เป็น 'ขั้นสุดท้าย' เพื่อให้คอมไพเลอร์อาจพบและตั้งค่าสถานะการกำหนดใหม่ใด ๆ
ในการหวนกลับ
ดังที่ได้กล่าวไว้ในคำตอบอื่น ๆ ... เนื่องจากเป้าหมายการออกแบบดั้งเดิมของ Java ในการช่วยเหลือโปรแกรมเมอร์เพื่อหลีกเลี่ยงข้อผิดพลาดที่เป็นใบ้เช่นการอ่านที่ผ่านมาในตอนท้ายของอาร์เรย์ Java ควรได้รับการออกแบบมาเพื่อบังคับใช้พารามิเตอร์ / อาร์กิวเมนต์ตัวแปรทั้งหมดโดยอัตโนมัติ ในคำอื่น ๆข้อโต้แย้งที่ไม่ควรจะเป็นตัวแปร แต่ปัญหาหลังวิสัยทัศน์คือ 20/20 วิสัยทัศน์และนักออกแบบ Java มีมือเต็มในเวลา
ดังนั้นเพิ่มfinal
อาร์กิวเมนต์ทั้งหมดเสมอหรือไม่
เราควรจะเพิ่มfinal
พารามิเตอร์ method แต่ละอันและทุกๆอันที่ถูกประกาศ?
- ในทางทฤษฎีใช่
- ในทางปฏิบัติไม่
➥เพิ่มfinal
เฉพาะเมื่อโค้ดของเมธอดยาวหรือซับซ้อนซึ่งการโต้แย้งอาจทำให้เข้าใจผิดว่าเป็นตัวแปรโลคอลหรือสมาชิกและอาจได้รับมอบหมายอีกครั้ง
หากคุณซื้อไปสู่การปฏิบัติที่ไม่เคยกำหนดอาร์กิวเมนต์ใหม่คุณจะมีแนวโน้มที่จะเพิ่ม a final
ให้กับแต่ละข้อ แต่นี่เป็นเรื่องน่าเบื่อและทำให้การประกาศอ่านยากขึ้น
สำหรับรหัสสั้น ๆ final
ง่ายๆที่อาร์กิวเมนต์จะเห็นได้ชัดข้อโต้แย้งและไม่ได้เป็นตัวแปรท้องถิ่นหรือตัวแปรสมาชิกผมไม่รำคาญเพิ่ม หากรหัสค่อนข้างชัดเจนไม่มีโอกาสของฉันหรือโปรแกรมเมอร์คนอื่น ๆ ที่ทำการบำรุงรักษาหรือ refactoring โดยไม่ได้ตั้งใจทำให้เกิดข้อโต้แย้งตัวแปรเป็นสิ่งอื่นนอกเหนือจากการโต้แย้งแล้วไม่ต้องกังวล ในงานของฉันฉันเพิ่มfinal
เฉพาะรหัสที่เกี่ยวข้องที่ยาวหรือมากกว่าซึ่งข้อโต้แย้งอาจเข้าใจผิดว่าเป็นตัวแปรโลคอลหรือสมาชิก
เพิ่มอีกกรณีหนึ่งเพื่อความสมบูรณ์
public class MyClass {
private int x;
//getters and setters
}
void doSomething( final MyClass arg ) { // Mark argument as 'final'.
arg = new MyClass(); // Compiler error: The passed argument variable arg cannot be re-assigned to another object.
arg.setX(20); // allowed
// We can re-assign properties of argument which is marked as final
}