enums คืออะไรและทำไมจึงมีประโยชน์


488

วันนี้ฉันกำลังอ่านคำถามบางข้อในเว็บไซต์นี้และฉันพบว่ามีการกล่าวถึงenum การใช้รูปแบบซิงเกิลเกี่ยวกับประโยชน์ด้านความปลอดภัยของเธรดที่อ้างว่าเป็นประโยชน์ต่อโซลูชันดังกล่าว

ฉันไม่เคยใช้enums และฉันได้เขียนโปรแกรมใน Java มานานกว่าสองสามปีแล้ว และเห็นได้ชัดว่าพวกเขาเปลี่ยนไปมาก ตอนนี้พวกเขายังสนับสนุน OOP อย่างเต็มที่ด้วยตัวเอง

ตอนนี้ทำไมและสิ่งที่ฉันควรใช้ enum ในการเขียนโปรแกรมแบบวันต่อวัน?



ซ้ำได้ของEnum ใน Java ข้อดี?
finnw

คุณไม่สามารถสร้างอินสแตนซ์ enums ได้เนื่องจากมันมีตัวสร้างส่วนตัวพวกมันถูกสร้างอินสแตนซ์เมื่อเริ่มต้น jvm ดังนั้นซิงเกิลของ Enums จึงไม่ปลอดภัย
Arnav Joshi

คำตอบ:


633

คุณควรใช้ enums เมื่อตัวแปร (โดยเฉพาะพารามิเตอร์เมธอด) สามารถนำค่าที่เป็นไปได้หนึ่งชุดออกมา ตัวอย่างจะเป็นสิ่งต่างๆเช่นค่าคงที่ประเภท (สถานะสัญญา: "ถาวร", "ชั่วคราว", "ฝึกงาน") หรือตั้งค่าสถานะ ("เรียกใช้ตอนนี้", "เลื่อนการดำเนินการ")

ถ้าคุณใช้ enums แทนจำนวนเต็ม (หรือรหัส String) คุณเพิ่มการตรวจสอบเวลาคอมไพล์และหลีกเลี่ยงข้อผิดพลาดจากการส่งค่าคงที่ที่ไม่ถูกต้องและคุณบันทึกว่าค่าใดถูกกฎหมายที่จะใช้

BTW การใช้ enums มากเกินไปอาจหมายความว่าวิธีการของคุณทำมากเกินไป (มักจะดีกว่าที่จะมีวิธีแยกกันหลายวิธีแทนที่จะใช้วิธีหนึ่งที่ใช้หลายแฟล็กซึ่งแก้ไขสิ่งที่ทำ) แต่ถ้าคุณต้องใช้แฟล็กหรือรหัสประเภท enums เป็นวิธีที่จะไป

ตัวอย่างเช่นไหนดีกว่ากัน?

/** Counts number of foobangs.
 * @param type Type of foobangs to count. Can be 1=green foobangs,
 * 2=wrinkled foobangs, 3=sweet foobangs, 0=all types.
 * @return number of foobangs of type
 */
public int countFoobangs(int type)

กับ

/** Types of foobangs. */
public enum FB_TYPE {
 GREEN, WRINKLED, SWEET, 
 /** special type for all types combined */
 ALL;
}

/** Counts number of foobangs.
 * @param type Type of foobangs to count
 * @return number of foobangs of type
 */
public int countFoobangs(FB_TYPE type)

วิธีการเรียกเช่น:

int sweetFoobangCount = countFoobangs(3);

จากนั้นกลายเป็น:

int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET);

ในตัวอย่างที่สองเป็นที่ชัดเจนทันทีว่าได้รับอนุญาตประเภทใดเอกสารและการนำไปใช้ไม่สามารถซิงค์ได้และคอมไพเลอร์สามารถบังคับใช้สิ่งนี้ นอกจากนี้การโทรที่ไม่ถูกต้องเช่น

int sweetFoobangCount = countFoobangs(99);

เป็นไปไม่ได้อีกต่อไป


41
หากคุณใช้ enums และต้องการอนุญาตให้ใช้ค่าร่วมกันให้ใช้ EnumSet สิ่งนี้มาพร้อมกับผู้ช่วยที่เรียบร้อยทุกประเภทเช่น EnumSet สุดท้ายสาธารณะ <FB_TYPE> ALL = EnumSet.allOf (FB_TYPE.class)
RobAu

20
คำตอบเหล่านี้คือคำตอบที่ฉันชอบที่จะเห็นเพราะคนมีความพยายามจริง ๆ งานที่ดีที่ฉันเข้าใจในตอนนี้!
Dediqated

1
you should *always* use enums when a variable can only take one out of a small set of possible valuesฉันไม่คิดว่ามันเป็นความจริงว่า การใช้ค่าคงที่เป็น 'ค่าสถานะไบนารี' (พร้อมค่าตรรกะor) สามารถเป็นประโยชน์สำหรับแอปพลิเคชันแบบเรียลไทม์ที่คุณมีหน่วยความจำสั้น
Elist

@ รายการที่ใช้ enums จะเพิ่มความสามารถในการอ่านรหัสของคุณหากคุณใช้ค่าคงที่ในบางช่วงเวลาคุณหรือผู้สืบทอดของคุณไม่ทราบว่าทำไมมันถึงถูกใช้ ...
:)

136

เหตุใดจึงต้องใช้คุณสมบัติภาษาการเขียนโปรแกรม เหตุผลที่เรามีภาษาทั้งหมดสำหรับ

  1. โปรแกรมเมอร์สามารถแสดงอัลกอริทึมที่มีประสิทธิภาพและถูกต้องในคอมพิวเตอร์ฟอร์มได้
  2. ผู้ดูแลเพื่อให้เข้าใจอัลกอริทึมที่คนอื่นเขียนและทำการเปลี่ยนแปลงอย่างถูกต้อง

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ยังว่างอยู่สามารถสร้างอินสแตนซ์จำนวนเท่าใดก็ได้ นี้ไม่ดี. ทางออกเดียวคือการเพิ่มการเข้าถึงเพื่อปกป้องตัวแปรsynchronizedINSTANCE

อย่างไรก็ตามstatic finalรหัสข้างต้นไม่มีปัญหานี้ มันสร้างอินสแตนซ์อย่างกระตือรือร้นในเวลาโหลดคลาส การโหลดคลาสถูกทำข้อมูลให้ตรงกัน

enumเดี่ยวเป็นคนขี้เกียจอย่างมีประสิทธิภาพเพราะมันไม่ได้เริ่มต้นจนใช้งานครั้งแรก Java INSTANCEเริ่มต้นนอกจากนี้ยังมีข้อมูลตรงกันดังนั้นหลายหัวข้อไม่สามารถเริ่มต้นมากกว่าหนึ่งตัวอย่างของ คุณได้รับซิงเกิลที่เริ่มต้นอย่างขี้เกียจด้วยรหัสน้อยมาก เชิงลบเพียงอย่างเดียวคือไวยากรณ์ค่อนข้างคลุมเครือ คุณจำเป็นต้องรู้สำนวนหรือเข้าใจอย่างถี่ถ้วนว่าการโหลดและการกำหนดค่าเริ่มต้นของชั้นเรียนรู้ว่าเกิดอะไรขึ้น


15
ย่อหน้าสุดท้ายนั้นทำให้สถานการณ์ของฉันชัดเจนขึ้น ขอบคุณ! ผู้อ่านที่อ่านแบบอ่านไม่ออกควรอ่านซ้ำ
Basil Bourque

ผมได้อ่านข้อความนี้stackoverflow.com/questions/16771373/... ตอนนี้ฉันสับสนกับพาราล่าสุดของคุณ enum ไม่มีคุณสมบัติการกำหนดค่าเริ่มต้นอย่างไร
Deepankar Singh เมื่อ

static finalเขตข้อมูลจะเริ่มต้นได้ในเวลาเริ่มต้นเรียนไม่โหลดเวลา มันเหมือนกับการenumเริ่มต้นอย่างต่อเนื่อง (อันที่จริงมันเหมือนกันภายใต้ประทุน) นั่นเป็นสาเหตุที่การพยายามใช้โค้ดเริ่มต้นขี้เกียจ“ ฉลาด” สำหรับซิงเกิลตันนั้นไม่มีประโยชน์แม้แต่ในจาวาเวอร์ชันแรก
Holger

42

นอกเหนือจากกรณีการใช้งานที่กล่าวถึงแล้วฉันมักจะพบว่ามีประโยชน์ในการใช้รูปแบบกลยุทธ์ตามแนวทาง OOP ขั้นพื้นฐาน:

  1. มีรหัสที่ข้อมูลอยู่ (นั่นคือภายใน enum เอง - หรือบ่อยครั้งภายในค่าคงที่ enum ซึ่งอาจแทนที่วิธี)
  2. การนำอินเตอร์เฟสไปใช้ (หรือมากกว่า) เพื่อไม่ให้ผูกโค้ดไคลเอ็นต์กับ enum (ซึ่งควรจัดเตรียมชุดของการนำไปใช้เริ่มต้นเท่านั้น)

ตัวอย่างที่ง่ายที่สุดคือชุดของComparatorการนำไปใช้งาน:

enum StringComparator implements Comparator<String> {
    NATURAL {
        @Override
        public int compare(String s1, String s2) {
            return s1.compareTo(s2);
        }
    },
    REVERSE {
        @Override
        public int compare(String s1, String s2) {
            return NATURAL.compare(s2, s1);
        }
    },
    LENGTH {
        @Override
        public int compare(String s1, String s2) {
            return new Integer(s1.length()).compareTo(s2.length());
        }
    };
}

"รูปแบบ" นี้สามารถใช้ในสถานการณ์ที่ซับซ้อนมากขึ้นใช้ประโยชน์จากสารพัดทั้งหมดที่มาพร้อมกับ enum: วนซ้ำตามลำดับโดยอาศัยคำสั่งโดยนัยของพวกเขาดึงอินสแตนซ์โดยใช้ชื่อของมัน สำหรับบริบทเฉพาะเป็นต้นและคุณยังมีสิ่งนี้ซ่อนอยู่หลังอินเทอร์เฟซดังนั้นโค้ดของคุณจะทำงานร่วมกับการปรับใช้แบบกำหนดเองโดยไม่มีการดัดแปลงในกรณีที่คุณต้องการบางสิ่งที่ไม่สามารถใช้ได้ใน "ตัวเลือกเริ่มต้น"

ฉันเคยเห็นสิ่งนี้ประสบความสำเร็จในการนำไปใช้สำหรับการสร้างแบบจำลองแนวคิดของเวลาที่ละเอียด (รายวันรายสัปดาห์ ฯลฯ ) ที่ตรรกะทั้งหมดถูกห่อหุ้มใน Enum (เลือกเมล็ดที่ถูกต้องสำหรับช่วงเวลาที่กำหนดพฤติกรรมที่เฉพาะเจาะจงผูกพันแต่ละเม็ดเป็นค่าคงที่ วิธีการอื่น ๆ ) และยังคงGranularityเป็นบริการที่เห็นโดยชั้นบริการเป็นเพียงส่วนต่อประสาน


2
คุณสามารถเพิ่มCASE_INSENSITIVE { @Override public int compare(String s1, String s2) { return s1.compareToIgnoreCase(s2); }ได้ ข้อดีอย่างหนึ่งที่ยังไม่ได้กล่าวถึงคือคุณได้รับการสนับสนุนการทำให้เป็นอนุกรมที่มีประสิทธิภาพ แบบฟอร์มถาวรประกอบด้วยชื่อคลาสและชื่อคงที่เท่านั้นไม่ขึ้นอยู่กับรายละเอียดการใช้งานใด ๆ ของเครื่องมือเปรียบเทียบของคุณ
Holger

32

ไม่มีสิ่งที่มีคำตอบอื่น ๆ ได้ครอบคลุมที่ enums ให้มีประสิทธิภาพโดยเฉพาะอย่างยิ่งมีความสามารถในการที่จะมีวิธีการที่แม่แบบ วิธีการสามารถเป็นส่วนหนึ่งของฐาน enum และแทนที่โดยแต่ละประเภท และด้วยพฤติกรรมที่แนบมากับ enum บ่อยครั้งที่มันไม่จำเป็นต้องสร้าง if-else หรือคำสั่งสลับเมื่อโพสต์บล็อกนี้แสดง - ซึ่งenum.method()สิ่งที่เดิมจะถูกดำเนินการภายในเงื่อนไข ตัวอย่างเดียวกันนี้ยังแสดงให้เห็นถึงการใช้การนำเข้าแบบคงที่กับ enums เช่นเดียวกับการผลิต DSL ที่สะอาดกว่าเช่นรหัส

บางคุณสมบัติที่น่าสนใจอื่น ๆ รวมถึงความจริงที่ว่า enums ให้การดำเนินงานสำหรับequals(), toString()และhashCode()และดำเนินการและSerializableComparable

สำหรับบทสรุปที่สมบูรณ์ของสิ่งที่ enums มีให้ฉันขอแนะนำ Bruce Eckel's Thinking ใน Java รุ่นที่ 4ซึ่งอุทิศทั้งบทในหัวข้อ โดยเฉพาะอย่างยิ่งการส่องสว่างเป็นตัวอย่างที่เกี่ยวข้องกับเกมร็อค, กระดาษ, กรรไกร (เช่น RoShamBo) เป็น enums


23

จากเอกสาร Java -

คุณควรใช้ประเภท enum ทุกครั้งที่คุณต้องการแสดงชุดค่าคงที่ ซึ่งรวมถึงประเภท enum ธรรมชาติเช่นดาวเคราะห์ในระบบสุริยะของเราและชุดข้อมูลที่คุณทราบค่าที่เป็นไปได้ทั้งหมดในเวลารวบรวมตัวอย่างเช่นตัวเลือกในเมนูการตั้งค่าสถานะบรรทัดคำสั่งและอื่น ๆ

ตัวอย่างทั่วไปคือการแทนที่คลาสด้วยชุดของค่าคงที่ int สุดท้ายคงที่ส่วนตัว (ภายในจำนวนคงที่ที่เหมาะสมของค่าคงที่) ด้วยประเภท enum โดยทั่วไปถ้าคุณคิดว่าคุณรู้คุณค่าที่เป็นไปได้ทั้งหมดของ "บางสิ่ง" ในเวลารวบรวมคุณสามารถแสดงให้เห็นว่าเป็นประเภท enum Enums ให้ความสามารถในการอ่านและความยืดหยุ่นมากกว่าคลาสที่มีค่าคงที่

ข้อดีอื่น ๆ อีกเล็กน้อยที่ฉันสามารถนึกถึงประเภท enum พวกเขามักจะเป็นหนึ่งในตัวอย่างของคลาส Enum ที่เฉพาะเจาะจง (ดังนั้นแนวคิดของการใช้ enums เมื่อมาถึงเดี่ยว) ข้อดีอีกอย่างคือคุณสามารถใช้ enums เป็นประเภทในคำสั่ง switch-case นอกจากนี้คุณสามารถใช้toString ()บน enum เพื่อพิมพ์เป็นสตริงที่อ่านได้


8
คุณจะใช้ enum ทั้งหมด 366 วันในปีนี้หรือไม่? มันเป็นค่าคงที่ (366) ของค่าคงที่ (วันไม่เปลี่ยนแปลง) ดังนั้นสิ่งนี้ชี้ให้เห็นว่าคุณควร : - / ฉัน จำกัด ขนาดของชุดคงที่
moinudin

2
@marcog ด้วยความคิดที่ฉลาดคุณอาจสรุปวันในสัปดาห์และวันในแต่ละเดือนได้ด้วย enum ขนาดกะทัดรัด
James P.

1
การพูดของวันในสัปดาห์… DayOfWeekenum ถูกกำหนดไว้ล่วงหน้าสร้างขึ้นใน Java 8 และใหม่กว่าซึ่งเป็นส่วนหนึ่งของเฟรมเวิร์กjava.time (และย้อนกลับไปยัง Java 6 และ 7และAndroid )
Basil Bourque

19

ตอนนี้ทำไมและสิ่งที่ฉันควรใช้ enum ในการเขียนโปรแกรมแบบวันต่อวัน?

คุณสามารถใช้ Enum เพื่อแสดงค่าคงที่ขนาดเล็กหรือโหมดคลาสภายในพร้อมกับเพิ่มความสามารถในการอ่าน นอกจากนี้ Enums สามารถบังคับใช้ความแข็งแกร่งบางอย่างเมื่อใช้ในพารามิเตอร์วิธีการ พวกเขามีความเป็นไปได้ที่น่าสนใจในการส่งข้อมูลไปยังตัวสร้างเช่นในตัวอย่าง Planets บนไซต์ของ Oracleและตามที่คุณค้นพบแล้วยังช่วยให้วิธีง่ายๆในการสร้างรูปแบบซิงเกิล

เช่นLocale.setDefault(Locale.US)อ่านดีกว่าLocale.setDefault(1)และบังคับใช้การใช้ชุดค่าคงที่ที่แสดงใน IDE เมื่อคุณเพิ่ม.ตัวคั่นแทนจำนวนเต็มทั้งหมด


@arnt ฉันได้แก้ไขไวยากรณ์ในคำถามด้วย ขอบคุณ
James P.

13

Enumระบุชุดของค่าคงที่ในวิธีการจัดทำเอกสารด้วยตนเอง
พวกเขาทำให้รหัสของคุณชัดเจนยิ่งขึ้นและมีข้อผิดพลาดน้อยลง

ทำไมไม่ใช้StringหรือintแทนEnumค่าคงที่?

  1. คอมไพเลอร์จะไม่อนุญาตให้พิมพ์ผิดค่าทั้งสองจากชุดคงที่เนื่องจาก enums เป็นประเภทด้วยตนเอง ผลกระทบ:
    • คุณไม่จำเป็นต้องเขียนเงื่อนไขล่วงหน้า (หรือคู่มือif) เพื่อให้มั่นใจว่าข้อโต้แย้งของคุณอยู่ในช่วงที่ถูกต้อง
    • ประเภทคงที่มาฟรี
  2. Enums สามารถมีพฤติกรรมได้เหมือนกับคลาสอื่น ๆ
  3. คุณอาจต้องใช้หน่วยความจำในปริมาณใกล้เคียงกันเพื่อใช้Strings (ขึ้นอยู่กับความซับซ้อนของEnum)

ยิ่งกว่านั้นEnumอินสแตนซ์ของแต่ละรายการเป็นคลาสที่คุณสามารถกำหนดพฤติกรรมของแต่ละบุคคลได้

นอกจากนี้พวกเขามั่นใจความปลอดภัยหัวข้อเมื่อสร้างอินสแตนซ์ (เมื่อ enum มีการโหลด) ซึ่งได้เห็นโปรแกรมที่ดีในการลดความซับซ้อนของรูปแบบซิงเกิล

บล็อกนี้แสดงแอปพลิเคชั่นบางตัวของมันเช่นState Machineสำหรับตัวแยกวิเคราะห์


13

มันจะมีประโยชน์ที่จะรู้ว่าenumsเป็นเหมือนชั้นเรียนอื่น ๆ ที่มีสาขาและConstantprivate constructor

ตัวอย่างเช่น,

public enum Weekday
{
  MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
} 

คอมไพเลอร์รวบรวมมันดังนี้

class Weekday extends Enum
{
  public static final Weekday MONDAY  = new Weekday( "MONDAY",   0 );
  public static final Weekday TUESDAY = new Weekday( "TUESDAY ", 1 );
  public static final Weekday WEDNESDAY= new Weekday( "WEDNESDAY", 2 );
  public static final Weekday THURSDAY= new Weekday( "THURSDAY", 3 );
  public static final Weekday FRIDAY= new Weekday( "FRIDAY", 4 );
  public static final Weekday SATURDAY= new Weekday( "SATURDAY", 5 );
  public static final Weekday SUNDAY= new Weekday( "SUNDAY", 6 );

  private Weekday( String s, int i )
  {
    super( s, i );
  }

  // other methods...
}

12

enumหมายถึงenum eration เช่นการกล่าวถึง (จำนวนสิ่ง) หนึ่งต่อหนึ่ง

enumเป็นชนิดข้อมูลที่ประกอบด้วยคงตั้งค่าของค่าคงที่

หรือ

An enumเหมือนกับ a classโดยมีชุดอินสแตนซ์คงที่ที่รู้จักในเวลารวบรวม

ตัวอย่างเช่น:

public class EnumExample {
    interface SeasonInt {
        String seasonDuration();
    }

    private enum Season implements SeasonInt {
        // except the enum constants remaining code looks same as class
        // enum constants are implicitly public static final we have used all caps to specify them like Constants in Java
        WINTER(88, "DEC - FEB"), SPRING(92, "MAR - JUN"), SUMMER(91, "JUN - AUG"), FALL(90, "SEP - NOV");

        private int days;
        private String months;

        Season(int days, String months) { // note: constructor is by default private 
            this.days = days;
            this.months = months;
        }

        @Override
        public String seasonDuration() {
            return this+" -> "+this.days + "days,   " + this.months+" months";
        }

    }
    public static void main(String[] args) {
        System.out.println(Season.SPRING.seasonDuration());
        for (Season season : Season.values()){
            System.out.println(season.seasonDuration());
        }

    }
}

ข้อดีของ enum:

  • ปรับปรุง enum ความปลอดภัยของประเภทที่รวบรวมเวลาการตรวจสอบเพื่อหลีกเลี่ยงข้อผิดพลาดในเวลาทำงาน
  • enum สามารถใช้งานได้ง่ายในสวิตช์
  • Enum สามารถเคลื่อนที่ได้
  • enum สามารถมีฟิลด์ตัวสร้างและเมธอด
  • enum อาจนำอินเตอร์เฟสจำนวนมากมาใช้ แต่ไม่สามารถขยายคลาสใด ๆ ได้เนื่องจากจะขยายคลาส Enum ภายใน

สำหรับเพิ่มเติม


9

Enum คืออะไร

  • enum เป็นคำหลักที่กำหนดไว้สำหรับการแจงนับชนิดข้อมูลใหม่ การแจกแจง Typesafe ควรใช้อย่างอิสระ โดยเฉพาะอย่างยิ่งมันเป็นทางเลือกที่มีประสิทธิภาพสำหรับสตริงหรือค่าคงที่แบบง่ายที่ใช้ใน API ที่เก่ากว่าเพื่อแสดงชุดของรายการที่เกี่ยวข้อง

ทำไมต้องใช้ enum

  • enums เป็น subclasses สุดท้ายสุดท้ายของ java.lang.Enum
  • ถ้า enum เป็นสมาชิกของคลาสมันจะคงที่โดยปริยาย
  • ใหม่ไม่สามารถใช้กับ enum ได้แม้จะอยู่ในประเภท enum เอง
  • ชื่อและค่าของเพียงใช้ข้อความของค่าคง enum ในขณะที่ toString อาจถูกแทนที่เพื่อให้เนื้อหาใด ๆ หากต้องการ
  • สำหรับค่าคงที่ enum เท่ากับและ == จำนวนเท่ากันและสามารถใช้แทนกันได้
  • ค่าคง enum เป็นค่าคงที่สาธารณะสุดท้าย

บันทึก

  • enums ไม่สามารถขยายชั้นเรียนใด ๆ
  • Enum ไม่สามารถเป็นซูเปอร์คลาสได้
  • ลำดับของลักษณะที่ปรากฏของค่าคงที่ enum เรียกว่า "ลำดับธรรมชาติ" ของพวกเขาและกำหนดลำดับที่ใช้โดยรายการอื่นเช่นกัน: CompareTo ลำดับการวนซ้ำของค่า EnumSet, EnumSet.range
  • การแจงนับสามารถมีตัวสร้างบล็อกแบบคงที่และอินสแตนซ์ตัวแปรและวิธีการ แต่ไม่สามารถมีวิธีนามธรรม

4
คุณไม่ได้อธิบายว่าทำไมต้องใช้ enums คุณเพียงแค่แสดงคุณสมบัติหลายประการของ enums ภายใต้ส่วนหัวที่ไม่เกี่ยวข้อง
Duncan Jones

@DuncanJones ไม่ข้อกำหนดสุดท้ายคงที่ให้วัตถุประสงค์ในการใช้ enums หรือไม่
tinker_fairy

8

นอกเหนือจากที่คนอื่นพูดทั้งหมด .. ในโครงการที่เก่ากว่าที่ฉันเคยทำงานการสื่อสารระหว่างเอนทิตี้ (แอพพลิเคชั่นอิสระ) จำนวนมากใช้จำนวนเต็มซึ่งเป็นชุดเล็ก ๆ มันมีประโยชน์ในการประกาศชุดเช่นเดียวenumกับวิธีการคงที่เพื่อรับenumวัตถุจากvalueและ viceversa รหัสดูสะอาดตาสลับการใช้งานเคสและเขียนบันทึกได้ง่ายขึ้น

enum ProtocolType {
    TCP_IP (1, "Transmission Control Protocol"), 
    IP (2, "Internet Protocol"), 
    UDP (3, "User Datagram Protocol");

    public int code;
    public String name;

    private ProtocolType(int code, String name) {
        this.code = code;
        this.name = name;
    }

    public static ProtocolType fromInt(int code) {
    switch(code) {
    case 1:
        return TCP_IP;
    case 2:
        return IP;
    case 3:
        return UDP;
    }

    // we had some exception handling for this
    // as the contract for these was between 2 independent applications
    // liable to change between versions (mostly adding new stuff)
    // but keeping it simple here.
    return null;
    }
}

สร้างenumวัตถุจากค่าที่ได้รับ (เช่น 1,2) โดยใช้การProtocolType.fromInt(2) เขียนไปยังบันทึกโดยใช้myEnumObj.name

หวังว่านี่จะช่วยได้


6

Enum สืบทอดวิธีการทั้งหมดของการเรียนและระดับนามธรรมObject Enumดังนั้นคุณสามารถใช้มันเป็นวิธีในการสะท้อนการทำมัลติเธรดเซริงเทียบเท่ากันเป็นต้นหากคุณเพิ่งประกาศค่าคงที่แบบคงที่แทน Enum คุณจะไม่สามารถทำได้ นอกจากนั้นค่าของ Enum สามารถส่งผ่านไปยัง DAO layer ได้เช่นกัน

นี่คือตัวอย่างโปรแกรมที่จะสาธิต

public enum State {

    Start("1"),
    Wait("1"),
    Notify("2"),
    NotifyAll("3"),
    Run("4"),
    SystemInatilize("5"),
    VendorInatilize("6"),
    test,
    FrameworkInatilize("7");

    public static State getState(String value) {
        return State.Wait;
    }

    private String value;
    State test;

    private State(String value) {
        this.value = value;
    }

    private State() {
    }

    public String getValue() {
        return value;
    }

    public void setCurrentState(State currentState) {
        test = currentState;
    }

    public boolean isNotify() {
        return this.equals(Notify);
    }
}

public class EnumTest {

    State test;

    public void setCurrentState(State currentState) {
        test = currentState;
    }

    public State getCurrentState() {
        return test;
    }

    public static void main(String[] args) {
        System.out.println(State.test);
        System.out.println(State.FrameworkInatilize);
        EnumTest test=new EnumTest();
        test.setCurrentState(State.Notify);
        test. stateSwitch();
    }

    public void stateSwitch() {
        switch (getCurrentState()) {
        case Notify:
            System.out.println("Notify");
            System.out.println(test.isNotify());
            break;
        default:
            break;
        }
    }
}

4

ENum ย่อมาจาก "Enumerated Type" มันเป็นชนิดข้อมูลที่มีชุดค่าคงที่ซึ่งคุณกำหนดเอง


คุณยังไม่ได้อธิบายว่าทำไมต้องใช้ enum
Duncan Jones

4
ใช่ฉันทำ. คุณใช้เพื่อเก็บค่าคงที่ซึ่งคุณกำหนดด้วยตัวคุณเอง แอปพลิเคชันเฉพาะของมันขึ้นอยู่กับคุณ ไม่มีสิ่งใดที่จะบอกว่าเมื่อไหร่ทำไมหรือวิธีการใช้บางสิ่งบางอย่าง ขึ้นอยู่กับความต้องการของนักพัฒนา สิ่งที่คุณต้องเข้าใจคือสิ่งที่มันเป็นและวิธีการทำงาน
Steve

4

ในความคิดของฉันคำตอบทั้งหมดที่คุณได้รับในขณะนี้นั้นถูกต้อง แต่จากประสบการณ์ของฉันฉันจะแสดงมันด้วยคำสองสามคำ:

ใช้ enums หากคุณต้องการให้คอมไพเลอร์ตรวจสอบความถูกต้องของค่าของตัวระบุ

มิฉะนั้นคุณสามารถใช้สตริงเหมือนที่เคยทำ (อาจเป็นเพราะคุณกำหนด "อนุสัญญา" บางอย่างสำหรับแอปพลิเคชันของคุณ) และคุณจะมีความยืดหยุ่นมาก ... แต่คุณจะไม่ได้รับความปลอดภัย 100% ต่อการพิมพ์ผิดในสตริงของคุณ ในรันไทม์


3

ใช้ enums สำหรับ TYPE SAFETY นี่เป็นคุณสมบัติภาษาดังนั้นโดยปกติคุณจะได้รับ:

  • การสนับสนุนคอมไพเลอร์ (ดูปัญหาประเภททันที)
  • การสนับสนุนเครื่องมือใน IDE (การเติมอัตโนมัติในกรณีสวิตช์, กรณีที่หายไป, ค่าเริ่มต้นบังคับ, ... )
  • ในบางกรณีประสิทธิภาพการทำงานของ enum ก็ยอดเยี่ยมเช่นกัน ( EnumSet เป็นทางเลือกที่ปลอดภัยต่อการใช้"บิตแฟล็ก"แบบ int )

Enums สามารถมีวิธีการสร้างคุณยังสามารถใช้ enums ภายใน enums และรวม enums กับอินเทอร์เฟซ

คิดว่า enums เป็นประเภทเพื่อแทนที่ชุดค่าคงที่ int ที่กำหนดไว้อย่างดี (ซึ่ง Java 'สืบทอดมาจาก C / C ++) และในบางกรณีเพื่อแทนที่ค่าสถานะบิต

หนังสือเล่มนี้มีผลบังคับใช้ Java 2nd Editionมีทั้งบทเกี่ยวกับพวกเขาและเข้าไปในรายละเอียดเพิ่มเติม โปรดดูโพสต์ Stack Overflowนี้


2

Java ช่วยให้คุณสามารถ จำกัด ตัวแปรให้มีหนึ่งในค่าที่กำหนดไว้ล่วงหน้าเพียงไม่กี่ค่า - อีกนัยหนึ่งคือค่าหนึ่งจากรายการที่แจกแจง การใช้enumsสามารถช่วยลดข้อผิดพลาดในรหัสของคุณ นี่คือตัวอย่างของenumsการเรียนนอก:

enums coffeesize{BIG , HUGE , OVERWHELMING }; 
//This semicolon is optional.

ข้อกำหนดด้านนี้coffeesizeจะมีอย่างใดอย่างหนึ่งBIG, HUGEหรือOVERWHELMINGเป็นตัวแปร


2

Enum? ทำไมจึงควรใช้ ฉันคิดว่ามันเข้าใจมากขึ้นเมื่อคุณจะใช้ ฉันมีประสบการณ์เดียวกัน

สมมติว่าคุณมีการดำเนินการสร้างลบแก้ไขและอ่านฐานข้อมูล

ตอนนี้ถ้าคุณสร้าง enum เป็นการดำเนินการ:

public enum operation {
    create("1")
    delete("2")
    edit("3")
    read("4")

    // You may have is methods here
    public boolean isCreate() {
        return this.equals(create);
    }
    // More methods like the above can be written

}

ตอนนี้คุณอาจประกาศบางสิ่งเช่น:

private operation currentOperation;

// And assign the value for it 
currentOperation = operation.create

ดังนั้นคุณสามารถใช้มันได้หลายวิธี เป็นการดีที่จะมี enum สำหรับสิ่งที่เฉพาะเจาะจงเนื่องจากการดำเนินการฐานข้อมูลในตัวอย่างข้างต้นสามารถควบคุมได้โดยการตรวจสอบการดำเนินงานปัจจุบัน บางทีอาจพูดได้ว่าสิ่งนี้สามารถเกิดขึ้นได้กับตัวแปรและค่าจำนวนเต็มเช่นกัน แต่ฉันเชื่อว่า Enum เป็นวิธีที่ปลอดภัยกว่าและเป็นโปรแกรมเมอร์

อีกอย่าง: ฉันคิดว่าโปรแกรมเมอร์ทุกคนชอบบูลีนใช่ไหม? เนื่องจากสามารถเก็บได้สองค่าเท่านั้นจึงมีค่าเฉพาะสองค่า ดังนั้น Enum อาจคิดได้ว่ามีสิ่งอำนวยความสะดวกประเภทเดียวกันที่ผู้ใช้จะกำหนดจำนวนและประเภทของค่าที่จะจัดเก็บในลักษณะที่แตกต่างกันเล็กน้อย :)


1

จนถึงตอนนี้ฉันไม่เคยต้องการใช้ enums ฉันได้อ่านเกี่ยวกับพวกเขาตั้งแต่พวกเขาถูกนำมาใช้ในเสือโคร่ง 1.5 หรือรุ่นเพราะมันถูกเรียกคืนในวันนั้น พวกเขาไม่เคยแก้ไข 'ปัญหา' ให้ฉันจริงๆ สำหรับผู้ที่ใช้มัน (และฉันเห็นพวกเขาทำมากมาย) แน่นอนว่ามันใช้เพื่อจุดประสงค์บางอย่างแน่นอน เพียงแค่ 2 quid ของฉัน


1

มีคำตอบมากมายที่นี่เพียงต้องการชี้เฉพาะสองข้อ:

1) ใช้เป็นค่าคงที่ในSwitch-caseคำสั่ง สลับตัวพิมพ์เล็กและใหญ่ไม่อนุญาตให้คุณใช้วัตถุสตริงเป็นตัวพิมพ์ใหญ่ Enums มามีประโยชน์ เพิ่มเติม: http://www.javabeat.net/2009/02/how-to-use-enum-in-switch/

2) Implementing Singleton Design Pattern- Enum อีกครั้งมาช่วยเหลือ การใช้งานที่นี่: วิธีที่ดีที่สุดในการใช้ Enum เป็นซิงเกิลตันใน Java คืออะไร


1

สิ่งที่ทำให้ฉันในช่วงเวลา Ah-Ha คือความเข้าใจนี้: Enum มีผู้สร้างส่วนตัวสามารถเข้าถึงได้ผ่านการแจงนับสาธารณะเท่านั้น

enum RGB {
    RED("Red"), GREEN("Green"), BLUE("Blue");

    public static final String PREFIX = "color ";

    public String getRGBString() {
        return PREFIX + color;
    }

    String color;

    RGB(String color) {
        this.color = color;
    }
}

public class HelloWorld {
    public static void main(String[] args) {
        String c = RGB.RED.getRGBString();
        System.out.print("Hello " + c);
    }
}

1

สำหรับฉันที่จะทำให้โค้ดสามารถอ่านได้ในอนาคตกรณีการแจงนับที่มีประโยชน์มากที่สุดของการแจงนับจะแสดงในตัวอย่างถัดไป:

public enum Items {
    MESSAGES, CHATS, CITY_ONLINE, FRIENDS, PROFILE, SETTINGS, PEOPLE_SEARCH, CREATE_CHAT
}

@Override
public boolean onCreateOptionsMenu(Menu menuPrm) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menuPrm);
    View itemChooserLcl;
    for (int i = 0; i < menuPrm.size(); i++) {
        MenuItem itemLcl  = menuPrm.getItem(i);
            itemChooserLcl = itemLcl.getActionView();
            if (itemChooserLcl != null) {
                 //here Im marking each View' tag by enume values:
                itemChooserLcl.setTag(Items.values()[i]);
                itemChooserLcl.setOnClickListener(drawerMenuListener);
            }
        }
    return true;
}
private View.OnClickListener drawerMenuListener=new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Items tagLcl= (Items) v.getTag();
        switch (tagLcl){
            case MESSAGES: ;
            break;
            case CHATS : ;
            break;
            case CITY_ONLINE : ;
            break;
            case FRIENDS : ;
            break;
            case  PROFILE: ;
            break;
            case  SETTINGS: ;
            break;
            case  PEOPLE_SEARCH: ;
            break;
            case  CREATE_CHAT: ;
            break;
        }
    }
};

1

จากประสบการณ์ของฉันฉันได้เห็นการใช้ Enum บางครั้งทำให้ระบบเปลี่ยนยากมาก หากคุณใช้ Enum สำหรับชุดของค่าโดเมนที่เปลี่ยนแปลงบ่อยและมีคลาสและส่วนประกอบอื่น ๆ จำนวนมากที่ขึ้นอยู่กับมันคุณอาจต้องการพิจารณาไม่ใช้ Enum

ตัวอย่างเช่นระบบการซื้อขายที่ใช้ Enum สำหรับตลาด / การแลกเปลี่ยน มีตลาดอยู่มากมายและเกือบแน่ใจว่าจะมีระบบย่อยจำนวนมากที่ต้องเข้าถึงรายการตลาดนี้ ทุกครั้งที่คุณต้องการเพิ่มตลาดใหม่ในระบบของคุณหรือถ้าคุณต้องการลบตลาดเป็นไปได้ว่าทุกอย่างภายใต้ดวงอาทิตย์จะต้องถูกสร้างขึ้นมาใหม่และปล่อยออกมา

ตัวอย่างที่ดีกว่าน่าจะเป็นประเภทผลิตภัณฑ์ สมมติว่าซอฟต์แวร์ของคุณจัดการสินค้าคงคลังสำหรับห้างสรรพสินค้า มีหมวดหมู่ผลิตภัณฑ์จำนวนมากและสาเหตุหลายประการที่ทำให้รายการหมวดหมู่นี้เปลี่ยนแปลง ผู้จัดการอาจต้องการสต็อกสายผลิตภัณฑ์ใหม่กำจัดสายผลิตภัณฑ์อื่นและอาจจัดระเบียบหมวดหมู่ใหม่เป็นครั้งคราว หากคุณต้องสร้างและปรับใช้ระบบของคุณใหม่ทั้งหมดเพียงเพราะผู้ใช้ต้องการเพิ่มหมวดหมู่ผลิตภัณฑ์คุณก็ต้องทำสิ่งที่ง่ายและรวดเร็ว (เพิ่มหมวดหมู่) และทำให้มันยากและช้ามาก

Bottom line, Enums นั้นดีถ้าข้อมูลที่คุณแสดงนั้นมีความคงที่ตลอดเวลาและมีจำนวนการอ้างอิงที่ จำกัด แต่ถ้าข้อมูลเปลี่ยนแปลงไปมากและมีการพึ่งพามากคุณต้องมีบางสิ่งบางอย่างแบบไดนามิกที่ไม่ได้ตรวจสอบ ณ เวลารวบรวม (เช่นตารางฐานข้อมูล)


1

ซิงเกิลอิง enum

ดูทันสมัยที่ปัญหาเก่า

วิธีนี้ใช้ซิงเกิลตันโดยใช้ประโยชน์จากการรับประกันของ Java ว่าค่า enum ใด ๆ จะถูกสร้างอินสแตนซ์เพียงครั้งเดียวในโปรแกรม Java และ enum ให้การสนับสนุนโดยนัยสำหรับความปลอดภัยของเธรด เนื่องจากค่า Java enum นั้นสามารถเข้าถึงได้ทั่วโลกดังนั้นจึงสามารถใช้เป็นซิงเกิลตันได้

public enum Singleton {
    SINGLETON; 
    public void method() { }
}

มันทำงานอย่างไร ทีนี้โค้ดสองบรรทัดอาจถูกพิจารณาเป็นอย่างนี้:

public final static Singleton SINGLETON = new Singleton(); 

และเราจะได้อายุที่ดีเริ่มต้นเดี่ยวซิงเกิล

โปรดจำไว้ว่าเนื่องจากนี่เป็น enum คุณสามารถเข้าถึงอินสแตนซ์ผ่านได้Singleton.INSTANCEตลอดเวลาเช่นกัน:

Singleton s = Singleton.INSTANCE;
ข้อดี
  • เพื่อป้องกันการสร้างอินสแตนซ์อื่นของซิงเกิลในระหว่างการดีซีเรียลไลเซชันให้ใช้ enum แบบซิงเกิลเนื่องจากการจัดลำดับของ enum นั้นได้รับการดูแลโดย JVM Enum เป็นอันดับและ deserialization ทำงานแตกต่างจากวัตถุ Java ปกติ สิ่งเดียวที่ได้รับต่อเนื่องคือชื่อของค่า enum ในระหว่างกระบวนการดีซีเรียลไลเซชันvalueOfเมธอดenum ถูกใช้กับชื่อดีซีเรียลไลซ์เซชันเพื่อรับอินสแตนซ์ที่ต้องการ
  • ซิงเกิลอิง Enum ช่วยป้องกันตัวเองจากการโจมตีแบบสะท้อนภาพ ชนิด enum ขยายEnumคลาสjava อย่างแท้จริง เหตุผลที่การสะท้อนไม่สามารถใช้เพื่อสร้างอินสแตนซ์ของวัตถุประเภท enum ได้เนื่องจากข้อกำหนดของจาวาไม่อนุญาตและกฎนั้นถูกเข้ารหัสในการนำnewInstanceวิธีการของConstructorคลาสมาใช้ซึ่งมักใช้ในการสร้างวัตถุผ่านการสะท้อนกลับ:
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
    throw new IllegalArgumentException("Cannot reflectively create enum objects");
  • Enum ไม่ควรถูกโคลนเนื่องจากต้องมีหนึ่งอินสแตนซ์ที่แน่นอนของแต่ละค่า
  • รหัสพูดน้อยที่สุดในบรรดาสำนึกเดี่ยวทั้งหมด
ข้อเสีย
  • ซิงเกิลอิง enum ไม่อนุญาตให้เริ่มต้นขี้เกียจ
  • หากคุณเปลี่ยนการออกแบบของคุณและต้องการที่จะแปลงซิงเกิลตันของคุณเป็นมัลติตัน Enum จะไม่อนุญาตสิ่งนี้ รูปแบบ Multiton mapถูกนำมาใช้สำหรับการสร้างการควบคุมหลายกรณีซึ่งจะจัดการผ่านการใช้งานที่ แทนที่จะต้องเช่นเดียวต่อโปรแกรมประยุกต์ (เช่นjava.lang.Runtime) รูปแบบ Multiton แทนเพื่อให้แน่ใจเช่นเดียวต่อคีย์
  • Enum ปรากฏใน Java 5 เท่านั้นดังนั้นคุณจึงไม่สามารถใช้งานได้ในเวอร์ชันก่อนหน้า

รูปแบบซิงเกิลแต่ละอันมีข้อดีและข้อเสียแตกต่างกันไป

  • กระตือรือร้นโหลดซิงเกิลตัน
  • ดับเบิลล็อคการตรวจสอบเดี่ยว
  • สำนวนการเริ่มต้นตามความต้องการเจ้าของ
  • ซิงเกิลอิง enum

คำอธิบายโดยละเอียดแต่ละคนนั้นละเอียดเกินไปดังนั้นฉันแค่ใส่ลิงค์ไปยังบทความที่ดี - สิ่งที่คุณอยากรู้เกี่ยวกับซิงเกิล


0

ฉันจะใช้ enums เป็นเครื่องมือการทำแผนที่ที่มีประโยชน์โดยหลีกเลี่ยงหลายif-else อย่างหากวิธีการบางอย่างถูกนำไปใช้

public enum Mapping {

    ONE("1"),
    TWO("2");

    private String label;

    private Mapping(String label){
        this.label = label;
    }

    public static Mapping by(String label) {

        for(Mapping m: values() {
            if(m.label.equals(label)) return m;
        }

        return null;
    }

}

ดังนั้นวิธีการby(String label)ช่วยให้คุณได้รับค่าที่แจกแจงโดยไม่ระบุ นอกจากนี้หนึ่งสามารถประดิษฐ์การทำแผนที่ระหว่าง 2 enums ยังสามารถลอง '1 ต่อหลายคน' หรือ 'หลายต่อหลายคน' นอกเหนือจากความสัมพันธ์เริ่มต้น 'หนึ่งต่อหนึ่ง'

ในที่สุดenumก็เป็นคลาส Java ดังนั้นคุณสามารถมีmainวิธีการภายในซึ่งอาจมีประโยชน์เมื่อต้องการดำเนินการทำแผนที่บางอย่างargsทันที


0

แทนที่จะทำให้กลุ่มประกาศ int const

คุณสามารถจัดกลุ่มพวกเขาทั้งหมดใน 1 enum

ดังนั้นจึงจัดโดยกลุ่มสามัญที่พวกเขาอยู่


0

Enums เป็นเหมือนคลาส เช่นเดียวกับคลาสนอกจากนี้ยังมีวิธีการและคุณสมบัติ

ความแตกต่างกับคลาสคือ: 1. ค่าคง enum เป็นสาธารณะคงที่ขั้นสุดท้าย 2. ไม่สามารถใช้ Enum เพื่อสร้างวัตถุและไม่สามารถขยายคลาสอื่น ๆ ได้ แต่มันสามารถใช้อินเตอร์เฟส


0

นอกจาก @BradB คำตอบ:

นั่นเป็นความจริง ... มันแปลกที่มันเป็นคำตอบเดียวที่พูดถึงมัน เมื่อผู้เริ่มต้นค้นพบ enums พวกเขารีบนำสิ่งนั้นไปใช้เป็นเคล็ดลับมายากลสำหรับการตรวจสอบตัวระบุที่ถูกต้องสำหรับคอมไพเลอร์ และเมื่อรหัสมีวัตถุประสงค์เพื่อใช้ในระบบกระจายพวกเขาร้องไห้ ... บางเดือนต่อมา รักษาความเข้ากันได้ย้อนหลังกับ enums ที่มีรายการค่าคงที่ไม่ใช่เป็นกังวลจริงและความเจ็บปวด นี่เป็นเพราะเมื่อคุณเพิ่มค่าให้กับ enum ที่มีอยู่การเปลี่ยนแปลงชนิดของมัน (แม้จะไม่มีชื่อ)

"โฮเดี๋ยวก่อนมันอาจจะเป็นแบบเดียวกันใช่มั้ยหลังจากนั้นพวกเขาจะใช้ชื่อเดียวกัน - และไม่ใช่แค่จำนวนเต็มใต้ฝากระโปรง" และด้วยเหตุผลเหล่านี้คอมไพเลอร์ของคุณอาจจะไม่ตั้งค่าสถานะการใช้คำจำกัดความหนึ่งของประเภทตัวเองที่มันคาดหวังอีก แต่ในความเป็นจริงมันเป็นประเภทที่แตกต่างกัน สิ่งสำคัญที่สุดคือพวกเขามีโดเมนข้อมูลที่แตกต่างกัน - ค่าที่ยอมรับได้ตามประเภท ด้วยการเพิ่มค่าเราได้เปลี่ยนประเภทของ enum อย่างมีประสิทธิภาพและทำให้ความเข้ากันได้ย้อนหลัง

สรุป: ใช้มันเมื่อคุณต้องการ แต่โปรดตรวจสอบว่าโดเมนข้อมูลที่ใช้เป็นประโยคที่รู้จักกันอยู่แล้วชุดถาวร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.