1.ความเป็นมาenumความเป็นมา

วันนี้เราจะสำรวจประเภทข้อมูลอื่นใน Java enum: ชื่อนี้enumมาจากคำว่าแจงนับ ประเภทข้อมูลนี้คืออะไรและมีไว้เพื่ออะไร

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

ตัวอย่างเช่นDayOfTheWeekประเภทสามารถรับค่าMONDAY, TUESDAY, WEDNESDAY, ... มีทั้งหมด 7 ค่า หรือMonthแบบเอาเฉพาะค่าJANUARY, FEBRUARY, MARCH, ... มีทั้งหมด 12 ค่า

แน่นอน คุณใช้ตัวเลข can ( intประเภท): 1— Monday, 2— Tuesday เป็นต้น แต่อาจมีคนกำหนดค่าที่ไม่ถูกต้อง เช่น8หรือ0ให้กับตัวแปรของคุณ โดยไม่ตั้งใจ

คุณอาจมีสถานการณ์ง่ายๆ ที่โปรแกรมเมอร์คนหนึ่งคิดว่าวันในสัปดาห์ (หรือเดือนต่างๆ ของปี) จะถูกนับโดยเริ่มจากศูนย์ ในขณะที่คนอื่นๆ คาดหวังว่าการนับจะเริ่มจากเลขหนึ่ง เป็นต้น

นั่นเป็นเหตุผลที่เปิดตัว Java enumซึ่งเป็นชนิดข้อมูลที่ประกอบด้วยชุดของค่าที่จำกัด


2. การประกาศประเภท

การประกาศประเภทข้อมูลใหม่enumมีลักษณะดังนี้:

enum TypeName
{
   VALUE1,
   VALUE2,
   VALUE3
}

ชื่อของประเภทใหม่ (คลาส) อยู่ที่ไหนTypeNameและค่าที่เป็นไปได้จะถูกคั่นด้วยเครื่องหมายจุลภาคและอยู่ในวงเล็บปีกกา: Value1, Value2,Value3

ตัวอย่างเช่น ลองสร้างของเราเองDayOfTheWeek enum:

รหัส บันทึก
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY
}
Dayแบบใหม่

จันทร์
อังคาร
พุธ
พฤหัสบดี
ศุกร์
เสาร์
อาทิตย์

นี่คือวิธีที่คุณกำหนดค่าให้กับตัวแปรประเภทใหม่ของเรา:

Day day = Day.MONDAY;

ตัวอย่าง:

รหัส บันทึก
Day day = Day.FRIDAY;
System.out.println(day);
เอาต์พุตหน้าจอจะเป็น:
FRIDAY


3. วิธีการของenum

ประเภทenumมีวิธีการในตัวหลายวิธี ซึ่งสองวิธีที่น่าสนใจมาก:

เมธอด สแตติกvalues()ส่งคืนอาร์เรย์ของค่าทั้งหมดของenumประเภท:

รหัส บันทึก
Day[] days = Day.values();

for (Day day: days)
   System.out.println(day);







System.out.println(days[2]);
ตัวแปรdaysเก็บอาร์เรย์ที่มีค่าประเภทDay(7 องค์ประกอบ)

แสดงเนื้อหาของอาร์เรย์บนหน้าจอ:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

WEDNESDAY

เมธอดordinal()จะส่งกลับเลขลำดับของค่าคงที่ คุณเรียกมันว่าenumค่ามากกว่าenumคลาส:

รหัส เอาต์พุตคอนโซล
System.out.println(Day.MONDAY.ordinal());
System.out.println(Day.FRIDAY.ordinal());
System.out.println(Day.SUNDAY.ordinal());
0
4
6


4. แปลงเป็นชั้นเรียน

ในความเป็นจริง ไม่มีอะไรวิเศษที่นี่ คอมไพเลอร์เพิ่งให้น้ำตาลวากยสัมพันธ์แก่เรา ในเวลารวบรวมDayenum จะถูกแปลงเป็นคลาสธรรมดา:

รหัสรุ่นง่าย บันทึก
public class Day
{
   public static final Day MONDAY = new Day(0);
   public static final Day TUESDAY = new Day(1);
   public static final Day WEDNESDAY = new Day(2);
   public static final Day THURSDAY = new Day(3);
   public static final Day FRIDAY = new Day(4);
   public static final Day SATURDAY = new Day(5);
   public static final Day SUNDAY = new Day(6);

    private static final Day[] array = {MONDAY, TUESDAY,
      WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY};

   private final int value;

   private Day (int value)
   {
      this.value = value;
   }

   public int ordinal()
   {
      return this.value;
   }

   public static Day[] values()
   {
      return array;
   }
}
Dayclass

รายการของค่าคงที่คงที่







อาร์เรย์ที่มีค่าทั้งหมดของDayenum ตัวแปร


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

DayconstructorDayDay



ordinalDay

value


Day

หากเราลบเมธอดและตัวแปรสแตติกทั้งหมดออกจากDayคลาส เราจะได้สิ่งต่อไปนี้:

รหัส บันทึก
public class Day
{
  private int value;

  private Day (int value)
  {
    this.value = value;
  }

  public int ordinal()
  {
    return this.value;
  }
}


ตัวแปรvalueเก็บค่าของDayวัตถุ วัตถุ

Dayสามารถสร้างได้ภายในDayคลาสเท่านั้น เนื่องจากตัวสร้างprivateคือ




วิธีordinal()การส่งกลับvalueของDayวัตถุ

กล่าวอีกนัยหนึ่งไม่มีอะไรน่ากลัวเกิดขึ้นที่นี่ คอมไพลเลอร์สร้าง คลาส เพิ่มค่าคง ที่Dayที่แสดงenumค่า เพิ่มเมธอดที่จำเป็น และสร้างคลาสคอนสตรัคเตอร์ privateเราจะดูว่าตัวสร้างทำงานอย่างไรในภายหลัง

หวังว่าตอนนี้คงจะชัดเจนแล้วว่าทำไมเราจึงกำหนดค่าให้กับตัวแปรด้วยวิธีนี้:

Day day = Day.MONDAY;

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



5. วิธีการเพิ่มเติมของenum

ทุกenumชั้นเรียนมีคุณสมบัติที่น่าสนใจหลายประการ

การแปลงเป็นและจากสตริง

ในการแปลงออบเจกต์ enum เป็นสตริง คุณต้องเรียกtoString()เมธอด ของมัน

String str = Day.MONDAY.toString();

หากต้องการแปลงในทิศทางอื่น (จากสตริงเป็นDayวัตถุ) คุณสามารถใช้valueOf()วิธีคงที่:

Day day = Day.valueOf("MONDAY");

สะดวกมากและจะเป็นประโยชน์ในหลายกรณี

การแปลงเป็นตัวเลขและย้อนกลับอีกครั้ง

คุณรู้วิธีแปลงenumวัตถุเป็นตัวเลขแล้ว: เรียกordinal()เมธอด:

int index = Day.MONDAY.ordinal();

ในการแปลงในทิศทางอื่น (จากตัวเลขเป็นDayวัตถุ) คุณต้องมีโครงสร้างที่โปร่งใสมากขึ้น:

Day day = Day.values()[2];

ตัวอย่าง:

รหัส บันทึก
Day day = Day.MONDAY;
int index = day.ordinal();
Day newDay = Day.values()[index+2];
วันจันทร์
รับดัชนีของวันจันทร์: 0
วันในสัปดาห์ 2 วันหลังจากวันจันทร์

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



6. เพิ่มวิธีการของคุณเองในenum

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

จากนั้นเราสามารถเพิ่มรหัสต่อไปนี้:

รหัส บันทึก
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY;

   public static List<Day> asList()
   {
      ArrayList<Day> list = new ArrayList<Day>();

      Collections.addAll(list, values());

      return list;
   }

}








ต้องระบุเครื่องหมายอัฒภาคหลังรายการค่า



สร้างArrayListวัตถุ

เพิ่มค่าในอาร์เรย์ที่ส่งคืนโดยvalues()เมธอด
ส่งคืนรายการ

ตอนนี้วิธีนี้สามารถเรียกใช้ในรหัส:

รหัส บันทึก
List<Day> list = Day.asList();
ตัวแปรlistจะเก็บรายการค่าทั้งหมดDay enumของ