JavaRush /จาวาบล็อก /Random-TH /การแจงนับใน Java (java enum)
articles
ระดับ

การแจงนับใน Java (java enum)

เผยแพร่ในกลุ่ม
เมื่อเขียนโปรแกรม เรามักจะพบกับความจำเป็นในการจำกัดชุดของค่าที่ถูกต้องสำหรับประเภทข้อมูลบางประเภท ตัวอย่างเช่น วันในสัปดาห์สามารถมีได้ 7 ค่าที่แตกต่างกัน เดือนของปีสามารถมีได้ 12 ค่า และฤดูกาลสามารถมีได้ 4 ค่า เพื่อแก้ไขปัญหาดังกล่าว ภาษาโปรแกรมที่พิมพ์แบบคงที่จำนวนมากจะมีประเภทข้อมูลพิเศษ - การแจงนับ ( enum) การแจงนับไม่ปรากฏใน Java ทันที มีการแนะนำ โครงสร้างภาษาพิเศษenumโดยเริ่มจากเวอร์ชัน 1.5 เมื่อถึงจุดนี้ โปรแกรมเมอร์ได้ใช้วิธีการอื่นในการแจงนับ การแจงนับใน Java (java enum) - 1

การก่อสร้างแจงนับ

เริ่มต้นด้วยตัวอย่าง เรามาอธิบายenumประเภทข้อมูลสำหรับจัดเก็บฤดูกาลโดยใช้:
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
ตัวอย่างการใช้งานง่ายๆ:
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
ด้วยเหตุนี้SUMMER จะถูก พิมพ์ ลงบนคอนโซล ฉันคิดว่าตัวอย่างชัดเจนและไม่ต้องการคำอธิบาย

เอนัมคือคลาส

โดยการประกาศenumเราจะสร้างคลาสที่ได้รับมาjava.lang.Enumจาก โดยทั่วไปการก่อสร้างenum Season { ... }จะเทียบเท่าclass Season extends java.lang.Enum { ... }กับ และถึงแม้ว่าคอมไพลเลอร์จะไม่อนุญาตให้เราสืบทอดจากjava.lang.Enumเราอย่างชัดเจน แต่ก็ยังง่ายต่อการตรวจสอบว่าenumมันได้รับการสืบทอดโดยใช้reflection:
System.out.println(Season.class.getSuperclass());
สิ่งต่อไปนี้จะปรากฏบนคอนโซล:
class java.lang.Enum
การสืบทอดที่แท้จริงจะดำเนินการโดยอัตโนมัติสำหรับเราโดยคอมไพเลอร์ Java ต่อไป เรามาตกลงที่จะเรียกคลาสที่สร้างโดยคอมไพเลอร์เพื่อใช้การแจงนับ - enumคลาส และค่าที่เป็นไปได้ของประเภทที่แจกแจงเป็นenumองค์ประกอบ -a

สมาชิก Enum เป็นอินสแตนซ์enumของคลาสที่สามารถเข้าถึงได้แบบคงที่

องค์ประกอบenum Season (WINTER, SPRING и т.д.)เป็นอินสแตนซ์ที่เข้าถึงได้แบบคงที่ของenum-class Seasonความพร้อมใช้งานคงที่ช่วยให้เราทำการเปรียบเทียบโดยใช้ตัวดำเนินการเปรียบเทียบ==อ้างอิง ตัวอย่าง:
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;

ชื่อและหมายเลขลำดับขององค์ประกอบแจงนับ

ตามที่กล่าวไว้ก่อนหน้านี้enum-class ใด ๆ สืบทอดjava.lang.Enumซึ่งมีหลายวิธีที่เป็นประโยชน์สำหรับการแจงนับทั้งหมด ตัวอย่าง:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
ผลลัพธ์จะเป็น:
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
วิธีการต่างๆname()และ แสดง ไว้ ที่ toString()นี่ ordinal()ความหมายของวิธีการต่างๆ นั้นชัดเจน ควรสังเกตว่าวิธีการเหล่านี้สืบทอด enumมาจากคลาส การรับองค์ประกอบโดยการแสดงสตริงของชื่อบ่อยครั้งงานเกิดขึ้นจากการรับองค์ประกอบด้วยการแสดงสตริง เพื่อวัตถุประสงค์เหล่านี้ ในแต่ละ-class คอมไพลเลอร์จะสร้างวิธีสแตติกพิเศษโดยอัตโนมัติ: ซึ่งส่งคืนองค์ประกอบการแจงนับที่มีชื่อเท่ากับ ตัวอย่างการใช้งาน: java.lang.Enumenumenumenumpublic static EnumClass valueOf(String name)EnumClassname
String name = "WINTER";
Season season = Season.valueOf(name);
จากการรันโค้ด ตัวแปรซีซันจะSeason.WINTERเท่ากับ โปรดทราบว่าหากไม่พบองค์ประกอบIllegalArgumentException จะถูกส่งออกไป และหากมีค่าเท่าnameกันNullPointerException จะถูกโยนทิ้ง โดยวิธีการนี้มักจะถูกลืม ด้วยเหตุผลบางประการ หลายๆ คนเชื่อมั่นอย่างยิ่งว่าหากฟังก์ชันรับหนึ่งอาร์กิวเมนต์และภายใต้เงื่อนไขบางประการได้ส่งIllegalArgumentException จากนั้นเมื่อส่งผ่านที่นั่นIllegalArgumentExceptionก็จะถูกโยนด้วยเช่นกัน แต่นั่นอยู่นอกประเด็น มาต่อกัน การรับองค์ประกอบทั้งหมดของการแจงนับ บางครั้งคุณจำเป็นต้องได้รับรายการองค์ประกอบทั้งหมดของ -คลาส ณ รันไทม์ เพื่อวัตถุประสงค์เหล่านี้คอมไพลเลอร์จะสร้างเมธอดในแต่ละ -class ตัวอย่างการใช้งาน: nullnullenumenumpublic static EnumClass[] values()
System.out.println(Arrays.toString(Season.values()));
เราได้รับผลลัพธ์:
[WINTER, SPRING, SUMMER, AUTUMN]
โปรดทราบว่าไม่มีการกำหนดวิธีการvalueOf()หรือวิธีการvalues()ในชั้นjava.lang.Enumเรียน แต่จะถูกเพิ่มโดยอัตโนมัติโดยคอมไพเลอร์เมื่อenumมีการคอมไพล์ -class การเพิ่มวิธีการของคุณเองในenum-class คุณมีโอกาสที่จะเพิ่มวิธีการของคุณเองทั้งในenum-class และองค์ประกอบ: การแจงนับใน Java (java enum) - 2เหมือนกัน แต่มีความหลากหลาย: การแจงนับใน Java (java enum) - 3ตัวอย่างสุดท้ายแสดงให้เห็นถึงการใช้การสืบทอดในenum. เพิ่มเติมเกี่ยวกับเรื่องนี้ในภายหลัง การสืบทอดenum ใน Java enumช่วยให้คุณสามารถใช้ลำดับชั้นของคลาสได้ ซึ่งอ็อบเจ็กต์ของคลาสนั้นถูกสร้างขึ้นในอินสแตนซ์เดียวและสามารถเข้าถึงได้แบบคงที่ ในกรณีนี้ องค์ประกอบenumสามารถมีตัวสร้างของตัวเองได้ ยกตัวอย่าง: ที่ นี่เราการแจงนับใน Java (java enum) - 4ประกาศการแจงนับTypeด้วยสามองค์ประกอบINTและ คอมไพเลอร์จะสร้างคลาสและอ็อบเจ็กต์ต่อไปนี้: INTEGERSTRING
  • Type- คลาสที่ได้มาจากjava.lang.Enum
  • INT— วัตถุของคลาสที่ 1 ที่ได้มาจากType
  • INTEGER— วัตถุของคลาสที่ 2 ที่ได้มาจากType
  • STRING— วัตถุชั้นที่ 3 ที่ได้มาจากType
คลาสที่ ได้รับมาสามคลาสจะถูกสร้างขึ้นด้วยวิธี polymorphic Object parse(String)และตัวสร้าง Type(..., boolean)ในเวลาเดียวกันวัตถุของคลาสINTและมีอยู่ในสำเนาเดียวและสามารถเข้าถึงได้แบบคงINTEGERที่ STRINGคุณสามารถตรวจสอบสิ่งนี้ได้:
System.out.println(Type.class);
System.out.println(Type.INT.getClass() + " " + Type.INT.getClass().getSuperclass());
System.out.println(Type.INTEGER.getClass() + " " + Type.INTEGER.getClass().getSuperclass());
System.out.println(Type.STRING.getClass()  + " " + Type.STRING.getClass().getSuperclass());
เราได้รับผลลัพธ์:
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
จะเห็นได้ว่าคอมไพเลอร์สร้างคลาสขึ้นมา 1 คลาสTypeและคลาส 3 nestedคลาสที่ได้มาจากType.

ถอดรหัสคลาส enum พร้อมการสืบทอด

เพื่อยืนยันข้างต้น เรายังนำเสนอผลลัพธ์ของการถอดรหัสการแจงนับTypeจากตัวอย่างด้านบน: การแจงนับใน Java (java enum) - 5

การแจงนับและพหุสัณฐานแบบพาราเมตริก

ผู้อ่านอาจสงสัยว่า: " เหตุใดการแจงนับประเภทข้างต้นจึงไม่ใช้ยาชื่อสามัญ " enumความจริงก็คือว่าใน Java ห้ามใช้ยาชื่อสามัญ ดังนั้นตัวอย่างต่อไปนี้จะไม่คอมไพล์:
enum Type<T> {}

การศึกษาต่อ

เพื่อความเข้าใจที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับวิธีการทำงานของการแจงนับใน Java ฉันขอแนะนำให้คุณทำความคุ้นเคยกับซอร์สโค้ดของคลาสjava.lang.Enumและใช้ตัวถอดรหัส Jad เพื่อศึกษาโค้ดที่สร้างขึ้น นอกจากนี้ การศึกษาซอร์สโค้ดไลบรารี Java จำเป็นอย่างยิ่งในการทำความเข้าใจว่ากลไกต่างๆ ใน ​​Java ทำงานกี่กลไก และมีประโยชน์ในการอ้างอิงสำหรับการออกแบบเชิงวัตถุ ลิงก์ไปยังแหล่งที่มาดั้งเดิม: http://alexander.lds.lg.ua/
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION