Enum trong Java là một kiểu dữ liệu đặc biệt của Java được sử dụng để định nghĩa các tập hợp các hằng số. Cụ thể hơn, Java enum là một kiểu đặc biệt của lớp trong Java. Một enum có thể chứa các trường, phương thức và Constructor.
Nó có thể được sử dụng để định nghĩa các ngày trong tuần (SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY), các mùa trong năm (SPRING, SUMMER, FALL, WINTER), …
Java enum đã được thêm vào trong Java 5 cùng một số tính năng khác.
LUYỆN THI CHỨNG CHỈ OCA
Ví dụ Enum trong Java
Từ khóa Enum trong Java được sử dụng để tạo một kiểu enum. Hãy xem chương trình ví dụ java enum sau:
public
enum ThreadStates { START, RUNNING, WAITING, DEAD; }Code language:
PHP
(
php
)
Trong ví dụ trên, ThreadStates là enum với các trường hằng số cố định START, RUNNING, WAITING và DEAD.
Java Enum vs Hằng số
Bây giờ chúng ta hãy xem enum tốt hơn các hằng số bình thường trong các lớp Java như thế nào.
Hãy tạo ra một class hằng số tương tự:
{
public
class
ThreadStatesConstant
public
static
final
int START =1
;public
static
final
int WAITING =2
;public
static
final
int RUNNING =3
;public
static
final
int DEAD =4
; }Code language:
PHP
(
php
)
Bây giờ chúng ta hãy xem cách cả enum và hằng số được sử dụng trong một chương trình java:
private
static
void benefitsOfEnumOverConstants() { simpleEnumExample(ThreadStates.START); simpleEnumExample(ThreadStates.WAITING); simpleEnumExample(ThreadStates.RUNNING); simpleEnumExample(ThreadStates.DEAD); simpleEnumExample(null
); simpleConstantsExample(1
); simpleConstantsExample(2
); simpleConstantsExample(3
); simpleConstantsExample(4
); simpleConstantsExample(5
); }private
static
void simpleEnumExample(ThreadStates th) {if
(th == ThreadStates.START) System.out.println("Thread started"
);else
if
(th == ThreadStates.WAITING) System.out.println("Thread is waiting"
);else
if
(th == ThreadStates.RUNNING) System.out.println("Thread is running"
);else
System.out.println("Thread is dead"
); }private
static
void simpleConstantsExample(int i) {if
(i == ThreadStatesConstant.START) System.out.println("Thread started"
);else
if
(i == ThreadStatesConstant.WAITING) System.out.println("Thread is waiting"
);else
if
(i == ThreadStatesConstant.RUNNING) System.out.println("Thread is running"
);else
System.out.println("Thread is dead"
); }Code language:
PHP
(
php
)
Nếu chúng ta nhìn vào ví dụ trên, chúng ta có hai rủi ro khi sử dụng các hằng số được enum giải quyết.
- Chúng ta có thể truyền bất kỳ hằng số int nào cho
- Chúng ta có thể thay đổi giá trị hằng số int trong class ThreadStatesConstant nhưng chương trình trên sẽ không ném ra bất kỳ ngoại lệ nào. Chương trình của tôi có thể không hoạt động như mong đợi nhưng nếu tôi thay đổi các hằng số enum, chúng tôi sẽ gặp lỗi thời gian biên dịch loại bỏ mọi khả năng xảy ra sự cố thời gian chạy.
Các phương thức Java Enum
Bây giờ chúng ta hãy xem thêm các tính năng của java enum với một ví dụ.
import java.io.Closeable; import java.io.IOException;
public
enum ThreadStatesEnum implements Closeable{ START(1
){ @Overridepublic
String toString(){return
"START implementation. Priority="
+getPriority(); } @Overridepublic
String getDetail() {return
"START"
; } }, RUNNING(2
){ @Overridepublic
String getDetail() {return
"RUNNING"
; } }, WAITING(3
){ @Overridepublic
String getDetail() {return
"WAITING"
; } }, DEAD(4
){ @Overridepublic
String getDetail() {return
"DEAD"
; } };private
int priority;public
abstract
String getDetail();private
ThreadStatesEnum(int i){ priority = i; }public
int getPriority(){return
this.priority; }public
void setPriority(int p){ this.priority = p; } @Overridepublic
String toString(){return
"Default ThreadStatesConstructors implementation. Priority="
+getPriority(); } @Overridepublic
void close() throws IOException { System.out.println("Close of Enum"
); } }Code language:
PHP
(
php
)
Các điểm quan trọng của Java Enum
Dưới đây là một số điểm quan trọng đối với Enums trong Java.
- Tất cả java enum ngầm mở rộng
java.lang.Enum
lớp mà kéo dài lớp Object và dụng cụ Serializable và tương đương interface. Vì vậy, chúng tôi không thể mở rộng bất kỳ lớp nào trong enum. - Vì enum là một từ khóa nên chúng ta không thể kết thúc tên gói với nó, ví dụ như
com.journaldev.enum
tên gói không hợp lệ. - Enum có thể implement . Như trong ví dụ trên enum, nó đang triển khai
Closeable
giao diện. - Các hàm tạo enum luôn ở chế độ riêng tư.
- Chúng ta không thể tạo phiên bản của enum bằng toán tử new.
- Chúng ta có thể khai báo các phương thức trừu tượng trong java enum, sau đó tất cả các trường enum phải triển khai phương thức trừu tượng. Trong ví dụ trên
getDetail()
là phương thức trừu tượng và tất cả các trường enum đã triển khai nó. - Chúng ta có thể định nghĩa một phương thức trong enum và các trường enum cũng có thể ghi đè chúng. Ví dụ,
toString()
phương thức được định nghĩa trong enum và trường enum START đã ghi đè nó. - Các trường enum trong Java có không gian tên, chúng ta chỉ có thể sử dụng trường enum với tên lớp như
ThreadStates.START
- Enums có thể được sử dụng trong câu lệnh switch , chúng ta sẽ thấy nó hoạt động trong phần sau của hướng dẫn này.
- Chúng tôi có thể mở rộng enum hiện có mà không phá vỡ bất kỳ chức năng hiện có nào. Ví dụ: chúng ta có thể thêm một trường mới MỚI trong enum ThreadStates mà không ảnh hưởng đến bất kỳ chức năng hiện có nào.
- Vì các trường enum là hằng số, phương pháp hay nhất trong java là viết chúng bằng các chữ cái khối và gạch dưới cho khoảng trắng. Ví dụ EAST, WEST, EAST_DIRECTION, v.v.
- Các hằng số enum hoàn toàn là tĩnh và là cuối cùng
- Hằng số enum là cuối cùng nhưng biến của nó vẫn có thể được thay đổi. Ví dụ, chúng ta có thể sử dụng
setPriority()
phương thức để thay đổi mức độ ưu tiên của hằng số enum. Chúng ta sẽ thấy nó được sử dụng trong ví dụ dưới đây. - Vì các hằng số enum là cuối cùng, chúng ta có thể so sánh chúng một cách an toàn bằng cách sử dụng các phương thức “==” và equals (). Cả hai sẽ có cùng một kết quả.
Java EnumSet, EnumMap, valueOf ()
Bây giờ chúng ta đã biết hầu hết các tính năng của Enum, chúng ta hãy xem chương trình ví dụ Java Enum. Sau đó, chúng ta sẽ tìm hiểu thêm một số tính năng của enum.
{ public
package com.journaldev.enums;
import
java.io.IOException;import
java.util.EnumMap;import
java.util.EnumSet;import
java.util.Set; publicclass
JavaEnumExamples
static
void
main(String
[] args) throws IOException { usingEnumMethods(); usingEnumValueOf(); usingEnumValues(); usingEnumInSwitch(ThreadStatesEnum.START); usingEnumInSwitch(ThreadStatesEnum.DEAD); usingEnumMap(); usingEnumSet(); } privatestatic
void
usingEnumSet() { EnumSet enumSet = EnumSet.allOf(ThreadStatesEnum.class);for
(ThreadStatesEnum tsenum : enumSet){ System.out.println("Using EnumSet, priority = "
+tsenum.getPriority()); } } privatestatic
void
usingEnumMap() { EnumMap<ThreadStatesEnum,String
> enumMap =new
EnumMap<ThreadStatesEnum,String
>(ThreadStatesEnum.class); enumMap.put(ThreadStatesEnum.START,"Thread is started"
); enumMap.put(ThreadStatesEnum.RUNNING,"Thread is running"
); enumMap.put(ThreadStatesEnum.WAITING,"Thread is waiting"
); enumMap.put(ThreadStatesEnum.DEAD,"Thread is dead"
);Set
keySet = enumMap.keySet();for
(ThreadStatesEnum key : keySet){ System.out.println("key="
+key.toString()+":: value="
+enumMap.get(key)); } } privatestatic
void
usingEnumInSwitch(ThreadStatesEnum th) {switch
(th){case
START: System.out.println("START thread"
);break
;case
WAITING: System.out.println("WAITING thread"
);break
;case
RUNNING: System.out.println("RUNNING thread"
);break
;case
DEAD: System.out.println("DEAD thread"
); } } privatestatic
void
usingEnumValues() { ThreadStatesEnum[] thArray = ThreadStatesEnum.values();for
(ThreadStatesEnum th : thArray){ System.out.println(th.toString() +"::priority="
+th.getPriority()); } } privatestatic
void
usingEnumValueOf() { ThreadStatesEnum th = Enum.valueOf(ThreadStatesEnum.class,"START"
); System.out.println("th priority="
+th.getPriority()); } privatestatic
void
usingEnumMethods() throws IOException { ThreadStatesEnum thc = ThreadStatesEnum.DEAD; System.out.println("priority is:"
+thc.getPriority()); thc = ThreadStatesEnum.DEAD; System.out.println("Using overriden method."
+thc.toString()); thc = ThreadStatesEnum.START; System.out.println("Using overriden method."
+thc.toString()); thc.setPriority(10
); System.out.println("Enum Constant variable changed priority value="
+thc.getPriority()); thc.close(); } }Code language:
JavaScript
(
javascript
)
Trước khi giải thích các tính năng quan trọng khác của enum, chúng ta hãy xem đầu ra của chương trình trên.
priority is:
4
Using overriden method.Default
ThreadStatesConstructors implementation. Priority=4
Using overriden method.START implementation. Priority=1
Enum Constant variable changed priority value=10
Close of Enum th priority=10
START implementation. Priority=10
::priority=10
Default
ThreadStatesConstructors implementation. Priority=2
::priority=2
Default
ThreadStatesConstructors implementation. Priority=3
::priority=3
Default
ThreadStatesConstructors implementation. Priority=4
::priority=4
START thread DEAD thread key=START:: value=Thread is started key=RUNNING:: value=Thread is running key=WAITING:: value=Thread is waiting key=DEAD:: value=Thread is dead Using EnumSet, priority =10
Using EnumSet, priority =2
Using EnumSet, priority =3
Using EnumSet, priority =4
Code language:
PHP
(
php
)
Điểm quan trọng
- Các phương thức usingEnumMethods() chỉ ra cách tạo một đối tượng enum và cách chúng ta có thể sử dụng các phương thức của nó. Nó cũng cho thấy việc sử dụng phương thức setPriorty(int i) để thay đổi biến của enum.
- usingEnummValueOf() cho thấy cách sử dụng java.util.EnumValueOf(enumType, name) mà qua đó chúng ta có thể tạo một đối tượng enum từ String. Nó ném IllegalArgumentException nếu kiểu enum được chỉ định không có hằng số với tên được chỉ định hoặc đối tượng lớp được chỉ định không đại diện cho kiểu enum. Nó cũng ném NullPointerException nếu bất kỳ đối số nào là rỗng.
- Phương thức usingEnumValues() hiển thị cách sử dụng phương thức giá trị () trả về một mảng chứa tất cả các giá trị của enum theo thứ tự chúng được khai báo. Lưu ý rằng phương thức này được tạo tự động bởi trình biên dịch java cho mọi enum. Bạn sẽ không tìm thấy việc triển khai giá trị () trong lớp java.util.Enum.
- Các usingEnumInSwitch() chương trình phương pháp làm thế nào để sử dụng hằng enum trong trường hợp chuyển đổi.
- Phương pháp usingEnumMap() cho thấy việc sử dụng java.util.EnumMap, được giới thiệu trong Java 1.5 Collections Framework. EnumMap là triển khai Bản đồ để sử dụng với các khóa kiểu enum. Tất cả các khóa trong bản đồ enum phải đến từ một kiểu enum duy nhất được chỉ định, rõ ràng hoặc ngầm định, khi bản đồ được tạo. Chúng tôi không thể sử dụng null làm khóa cho EnumMap và EnumMap không được đồng bộ hóa.
- Phương thức usingEnumSet() hiển thị việc sử dụng java.util.EnumSet , là thiết lập triển khai để sử dụng với các kiểu enum. Tất cả các phần tử trong một tập hợp enum phải đến từ một kiểu enum duy nhất được chỉ định, rõ ràng hoặc ngầm định, khi tập hợp được tạo. EnumSet không được đồng bộ hóa và các phần tử rỗng không được phép. Nó cũng cung cấp một số phương pháp hữu ích như copyOf(Collection c), of(E first, E… rest)và complementOf(EnumSet s).
Trên đây là kiến thức về Enum và ví dụ Enum trong Java.
Happy learning!!!