เหตุใดจึงต้องใช้คุณสมบัติภาษาการเขียนโปรแกรม เหตุผลที่เรามีภาษาทั้งหมดสำหรับ
- โปรแกรมเมอร์สามารถแสดงอัลกอริทึมที่มีประสิทธิภาพและถูกต้องในคอมพิวเตอร์ฟอร์มได้
- ผู้ดูแลเพื่อให้เข้าใจอัลกอริทึมที่คนอื่นเขียนและทำการเปลี่ยนแปลงอย่างถูกต้อง
Enums ปรับปรุงทั้งความน่าจะเป็นของความถูกต้องและความสามารถในการอ่านโดยไม่ต้องเขียนจำนวนมาก หากคุณยินดีที่จะเขียนสำเร็จรูปคุณสามารถ "จำลอง" enums:
public class Color {
private Color() {} // Prevent others from making colors.
public static final Color RED = new Color();
public static final Color AMBER = new Color();
public static final Color GREEN = new Color();
}
ตอนนี้คุณสามารถเขียน:
Color trafficLightColor = Color.RED;
แผ่นความร้อนด้านบนมีผลเช่นเดียวกับ
public enum Color { RED, AMBER, GREEN };
ทั้งสองมีระดับการตรวจสอบความช่วยเหลือจากคอมไพเลอร์ในระดับเดียวกัน หม้อไอน้ำพิมพ์ได้มากขึ้น แต่การประหยัดการพิมพ์จำนวนมากทำให้โปรแกรมเมอร์มีประสิทธิภาพมากขึ้น(ดู 1) ดังนั้นจึงเป็นคุณสมบัติที่คุ้มค่า
มันก็คุ้มค่าด้วยเหตุผลอย่างน้อยหนึ่งข้อเช่นกัน:
สลับคำสั่ง
สิ่งหนึ่งที่การstatic final
จำลอง enum ด้านบนไม่ได้ให้คุณเป็นswitch
กรณีที่ดี สำหรับประเภท enum สวิตช์ Java ใช้ชนิดของตัวแปรเพื่ออนุมานขอบเขตของกรณี enum ดังนั้นสำหรับenum Color
ข้างต้นคุณเพียงแค่ต้องพูดว่า:
Color color = ... ;
switch (color) {
case RED:
...
break;
}
หมายเหตุมันไม่ได้Color.RED
อยู่ในกรณี หากคุณไม่ใช้ enum วิธีเดียวที่จะใช้ปริมาณที่มีชื่อด้วยswitch
คือ:
public Class Color {
public static final int RED = 0;
public static final int AMBER = 1;
public static final int GREEN = 2;
}
int
แต่ตอนนี้ตัวแปรที่จะถือสีต้องมีประเภท การตรวจสอบคอมไพเลอร์ที่ดีของ enum และการstatic final
จำลองหายไป ไม่ได้มีความสุข.
การประนีประนอมคือการใช้สมาชิกที่มีค่าสเกลาร์ในการจำลอง:
public class Color {
public static final int RED_TAG = 1;
public static final int AMBER_TAG = 2;
public static final int GREEN_TAG = 3;
public final int tag;
private Color(int tag) { this.tag = tag; }
public static final Color RED = new Color(RED_TAG);
public static final Color AMBER = new Color(AMBER_TAG);
public static final Color GREEN = new Color(GREEN_TAG);
}
ขณะนี้:
Color color = ... ;
switch (color.tag) {
case Color.RED_TAG:
...
break;
}
แต่ทราบว่ายิ่งสำเร็จรูปมากขึ้น!
ใช้ enum เป็นซิงเกิล
จากแผ่นความร้อนด้านบนคุณจะเห็นได้ว่าทำไม enum ถึงวิธีการใช้งานซิงเกิล แทนที่จะเขียน:
public class SingletonClass {
public static final void INSTANCE = new SingletonClass();
private SingletonClass() {}
// all the methods and instance data for the class here
}
แล้วเข้าถึงด้วย
SingletonClass.INSTANCE
เราสามารถพูดได้
public enum SingletonClass {
INSTANCE;
// all the methods and instance data for the class here
}
ซึ่งให้สิ่งเดียวกันกับเรา เราสามารถหลีกเลี่ยงสิ่งนี้ได้เพราะ Java enums ถูกนำไปใช้เป็นคลาสเต็มรูปแบบโดยมีน้ำตาลประโยคเล็ก ๆ น้อย ๆ ไหลอยู่ด้านบน นี่เป็นอีกครั้งที่น้อยกว่า boilerplate แต่มันไม่ชัดเจนเว้นแต่ว่าสำนวนที่คุ้นเคยกับคุณ ฉันยังไม่ชอบความจริงที่ว่าคุณได้ฟังก์ชั่น enum ต่าง ๆ แม้ว่ามันจะไม่สมเหตุสมผลสำหรับซิงเกิลตันord
และvalues
อื่น ๆ (จริง ๆ แล้วมันมีการจำลองที่ซับซ้อนกว่าที่Color extends Integer
จะใช้กับสวิตช์ได้ แต่มันก็ซับซ้อนกว่า แสดงให้เห็นอย่างชัดเจนว่าทำไมจึงenum
เป็นความคิดที่ดีกว่า)
ความปลอดภัยด้าย
ความปลอดภัยของเธรดเป็นปัญหาที่อาจเกิดขึ้นได้ก็ต่อเมื่อมีการสร้างซิงเกิลตันอย่างเกียจคร้านโดยไม่มีการล็อค
public class SingletonClass {
private static SingletonClass INSTANCE;
private SingletonClass() {}
public SingletonClass getInstance() {
if (INSTANCE == null) INSTANCE = new SingletonClass();
return INSTANCE;
}
// all the methods and instance data for the class here
}
หากมีหลายเธรดที่เรียกgetInstance
พร้อมกันในขณะที่INSTANCE
ยังว่างอยู่สามารถสร้างอินสแตนซ์จำนวนเท่าใดก็ได้ นี้ไม่ดี. ทางออกเดียวคือการเพิ่มการเข้าถึงเพื่อปกป้องตัวแปรsynchronized
INSTANCE
อย่างไรก็ตามstatic final
รหัสข้างต้นไม่มีปัญหานี้ มันสร้างอินสแตนซ์อย่างกระตือรือร้นในเวลาโหลดคลาส การโหลดคลาสถูกทำข้อมูลให้ตรงกัน
enum
เดี่ยวเป็นคนขี้เกียจอย่างมีประสิทธิภาพเพราะมันไม่ได้เริ่มต้นจนใช้งานครั้งแรก Java INSTANCE
เริ่มต้นนอกจากนี้ยังมีข้อมูลตรงกันดังนั้นหลายหัวข้อไม่สามารถเริ่มต้นมากกว่าหนึ่งตัวอย่างของ คุณได้รับซิงเกิลที่เริ่มต้นอย่างขี้เกียจด้วยรหัสน้อยมาก เชิงลบเพียงอย่างเดียวคือไวยากรณ์ค่อนข้างคลุมเครือ คุณจำเป็นต้องรู้สำนวนหรือเข้าใจอย่างถี่ถ้วนว่าการโหลดและการกำหนดค่าเริ่มต้นของชั้นเรียนรู้ว่าเกิดอะไรขึ้น