โดยทั่วไปอย่าใช้บล็อกเริ่มต้นแบบไม่คงที่ (และอาจหลีกเลี่ยงบล็อกแบบคงที่ด้วย)
ไวยากรณ์ที่สับสน
ดูคำถามนี้มี 3 คำตอบ แต่คุณหลอก 4 คนด้วยไวยากรณ์นี้ ฉันเป็นหนึ่งในนั้นและฉันเขียน Java มา 16 ปีแล้ว! เห็นได้ชัดว่าไวยากรณ์อาจเกิดข้อผิดพลาดได้ง่าย! ฉันจะอยู่ห่างจากมัน
ตัวสร้างเหลื่อม
สำหรับสิ่งที่ง่ายจริงๆคุณสามารถใช้ตัวสร้าง "เหลื่อม" เพื่อหลีกเลี่ยงความสับสนนี้:
public class Test {
private String something;
// Default constructor does some things
public Test() { doStuff(); }
// Other constructors call the default constructor
public Test(String s) {
this(); // Call default constructor
something = s;
}
}
รูปแบบการสร้าง
หากคุณต้องการ doStuff () ที่ส่วนท้ายของ Constructor แต่ละตัวหรือการกำหนดค่าเริ่มต้นที่ซับซ้อนอื่น ๆ บางทีรูปแบบการสร้างจะดีที่สุด Josh Blochแสดงเหตุผลหลายประการว่าทำไมผู้สร้างจึงเป็นความคิดที่ดี ผู้สร้างใช้เวลาเล็กน้อยในการเขียน แต่เขียนอย่างถูกต้องพวกเขามีความสุขที่จะใช้
public class Test {
// Value can be final (immutable)
private final String something;
// Private constructor.
private Test(String s) { something = s; }
// Static method to get a builder
public static Builder builder() { return new Builder(); }
// builder class accumulates values until a valid Test object can be created.
private static class Builder {
private String tempSomething;
public Builder something(String s) {
tempSomething = s;
return this;
}
// This is our factory method for a Test class.
public Test build() {
Test t = new Test(tempSomething);
// Here we do your extra initialization after the
// Test class has been created.
doStuff();
// Return a valid, potentially immutable Test object.
return t;
}
}
}
// Now you can call:
Test t = Test.builder()
.setString("Utini!")
.build();
Static Initializer Loops
ฉันเคยใช้คงที่ initializersที่มาก แต่บางครั้งก็วิ่งเข้าไปในลูปที่ 2 คลาสขึ้นอยู่กับบล็อกเริ่มต้นคงที่ของแต่ละคนที่ถูกเรียกก่อนที่ชั้นจะสามารถโหลดได้อย่างเต็มที่ สิ่งนี้ทำให้เกิด "ไม่สามารถโหลดคลาส" หรือข้อความแสดงข้อผิดพลาดที่คลุมเครือในทำนองเดียวกัน ฉันต้องเปรียบเทียบไฟล์กับเวอร์ชันการทำงานล่าสุดที่รู้จักในการควบคุมแหล่งที่มาเพื่อที่จะทราบว่าปัญหาคืออะไร ไม่สนุกเลย
การเริ่มต้น Lazy
บางที initializers คงดีสำหรับเหตุผลด้านประสิทธิภาพเมื่อทำงานและไม่สับสนเกินไป แต่โดยทั่วไปฉันชอบเริ่มต้นขี้เกียจเริ่มต้นคงที่ initializers วันนี้ เห็นได้ชัดว่าพวกเขาทำอะไรฉันยังไม่พบข้อผิดพลาดในการโหลดคลาสกับพวกเขาและพวกเขาทำงานในสถานการณ์เริ่มต้นมากกว่าบล็อกตัวเริ่มต้น
นิยามข้อมูล
แทนที่จะเริ่มต้นแบบคงที่สำหรับการสร้างโครงสร้างข้อมูล (เปรียบเทียบกับตัวอย่างในคำตอบอื่น ๆ ) ตอนนี้ฉันใช้ฟังก์ชันตัวช่วยกำหนดนิยามข้อมูลที่ไม่เปลี่ยนรูปของ Paguro :
private ImMap<String,String> days =
map(tup("mon", "monday"),
tup("tue", "tuesday"),
tup("wed", "wednesday"),
tup("thu", "thursday"),
tup("fri", "friday"),
tup("sat", "saturday"),
tup("sun", "sunday"));
Conculsion
ในการเริ่มต้นของ Java บล็อกเริ่มต้นเป็นวิธีเดียวที่จะทำบางสิ่ง แต่ตอนนี้พวกเขากำลังสับสนเกิดข้อผิดพลาดได้ง่ายและในกรณีส่วนใหญ่ถูกแทนที่ด้วยทางเลือกที่ดีกว่า (รายละเอียดด้านบน) เป็นเรื่องน่าสนใจที่จะรู้เกี่ยวกับการเริ่มต้นบล็อกในกรณีที่คุณเห็นพวกเขาในรหัสดั้งเดิมหรือพวกเขามาในการทดสอบ แต่ถ้าฉันทำรีวิวรหัสและฉันเห็นหนึ่งในรหัสใหม่ฉันจะขอให้คุณพิสูจน์เหตุผลว่าทำไมไม่มี ตัวเลือกข้างต้นมีความเหมาะสมก่อนที่จะให้รหัสของคุณนิ้วหัวแม่มือขึ้น