ในกรณีที่เราต้องการกำหนดกลุ่มของค่าหรือข้อมูลให้กับตัวแปร เพื่อป้องกันปัญหาการพิมพ์ผิดหรือเรียกใช้ค่าที่ไม่ได้คาดไว้ เราสามารถใช้ enum ช่วยได้
enum เป็นการกำหนดกลุ่มของค่าที่เป็นคอนแสตนท์ (constant) คือไม่สามารถเปลี่ยนค่าได้ โดยค่าที่กำหนดจะเป็นตัวอักษรใหญ่ เช่น กำหนดค่าสถานะของผู้ใช้งานตามตัวอย่างด้านล่าง
public enum UserStatus {
PENDING, ACTIVE, BLOCKED
}
เวลาเรียกใช้งาน enum จะกำหนดชนิดของข้อมูลของตัวแปรเป็น enum และอ่านค่ามาเก็บในตัวแปร ดังตัวอย่างด้านล่าง
UserStatus active = UserStatus.ACTIVE;
เราสามารถอ่านค่าของแต่ละคอนแสตนท์ใน enum ได้โดยใช้เมธอด name() ดังนี้ โดยระบุค่าที่ต้องการอ่านด้วยตัวอักษรเล็ก
System.out.println(active.name()); // ACTIVE
เราสามารถอ้างถึงแต่ละคอนแสตนท์ใน enum โดยใช้ชื่อของคอนแสตนท์แต่ละตัวได้ด้วยเมธอด valueOf() ดังนี้ โดยต้องระบุเป็นตัวอักษรใหญ่เท่านั้น
UserStatus blocked = UserStatus.valueOf(“BLOCKED”); // BLOCKED
เราสามารถอ่านค่าของแต่ละคอนแสตนท์ได้โดยเมธอด value() ดังตัวอย่างด้านล่าง เราอ่านค่าคอนแสตนท์ทั้งหมดไปเก็บในอาเรย์
UserStatus[] statuses = UserStatus.values(); // [PENDING, ACTIVE, BLOCKED]
เราสามารถอ่านค่าของแต่ละคอนแสตนท์ได้ด้วยเมธอด ordinal() โดยดัชนีจะเริ่มต้นจาก 0
System.out.println(active.ordinal()); // 1 (starting with 0)
System.out.println(UserStatus.BLOCKED.ordinal()); // 2
เราสามารถเปรียบเทียบข้อมูล enum ได้ด้วยเมธอด equal() หรือ == เช่น
System.out.println(active.equals(UserStatus.ACTIVE)); // true
System.out.println(active == UserStatus.ACTIVE); // true
เราสามารถวนลูปอ่านค่า enum ได้ตามตัวอย่างด้านล่าง
for (UserStatus status : UserStatus.values()) {
System.out.println(status);
}
/* the output is
PENDING
ACTIVE
BLOCKED
*/
เราอาจจะมองว่า enum เป็นเหมือนคลาสที่มีชุดของออบเจกต์ที่กำหนดไว้แล้วได้ด้วย เราจึงสามารถกำหนดฟิลด์ให้กับแต่ละคอนแสตนท์ (มองแต่ละคอนแสตนท์เป็นเหมืนอออบเจกต์นึง) และกำหนดเมธอดให้ enum ได้ดังตัวอย่างด้านล่าง
enum UserStatus {
PENDING(1, “aa”),
ACTIVE(2, “bb”),
BLOCK(3, “cc”);
int num;
String str;
UserStatus(int n, String s) { //คอนสตรัคเตอร์
this.num = n;
this.str = s;
}
public int getNum() {
return num;
}
public String getStr() {
return str;
}
public static UserStatus findByNum(int n) {
for (UserStatus value: values()) {
if (value.num == n) {
return value;
}
}
return null;
}
สังเกตุว่าเมื่อเรากำหนดฟิลด์ให้กับแต่ละคอนแสตนท์ของ enum จะต้องมีเมธอดคอนสตรัคเตอร์เพื่อจับคู่ค่าในฟิลด์กับแต่ละคอนแสตนท์ของ enum
จากตัวอย่างด้านบนเราสามารถสร้างเมธอดเพิ่มขึ้นมาเองได้ดังตัวอย่างเมธอด findByNum() ซึ่งจะคืนค่ากลับเป็น enum โดยมีตัวอย่างการใช้งานดังนี้
System.out.println(UserStatus.findByNum(1)); // ACTIVE
สังเกตเมธอด getNum() และ getStr() ลักษณะการใช้งานจะเป็นตามตัวอย่างด้านล่าง คือต้องอ้างถึงคอนแสตนท์ที่ต้องการด้วยซึ่งหากเรามองอีกมุมหนึ่งจะเหมือนว่าแต่ละคอนแสตนท์คือออบเจกต์และเราเรียกใช้เมธอด getNum() และ getStr()
ของออบเจกต์นั้นๆ
System.out.println(UserStatus.PENDING.getNum); // 1