Enum trong Java – Học Java

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.

  1. Chúng ta có thể truyền bất kỳ hằng số int nào cho phương thức simpleConstantsExample() nhưng chúng ta chỉ có thể truyền các giá trị cố định cho simpleEnumExample, vì vậy nó cung cấp sự an toàn về kiểu.
  2. 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

){ @Override

public

String toString(){

return

"START implementation. Priority="

+getPriority(); } @Override

public

String getDetail() {

return

"START"

; } }, RUNNING(

2

){ @Override

public

String getDetail() {

return

"RUNNING"

; } }, WAITING(

3

){ @Override

public

String getDetail() {

return

"WAITING"

; } }, DEAD(

4

){ @Override

public

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; } @Override

public

String toString(){

return

"Default ThreadStatesConstructors implementation. Priority="

+getPriority(); } @Override

public

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.

  1. Tất cả java enum ngầm mở rộng java.lang.Enumlớ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.
  2. 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.enumtên gói không hợp lệ.
  3. Enum có thể implement  . Như trong ví dụ trên enum, nó đang triển khai Closeablegiao diện.
  4. Các hàm tạo enum luôn ở chế độ riêng tư.
  5. Chúng ta không thể tạo phiên bản của enum bằng toán tử new.
  6. 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ó.
  7. 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ó.
  8. 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
  9. 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.
  10. 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.
  11. 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.
  12. Các hằng số enum hoàn toàn là tĩnh và là cuối cùng
  13. 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.
  14. 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.

package com.journaldev.enums;

import

java.io.IOException;

import

java.util.EnumMap;

import

java.util.EnumSet;

import

java.util.Set; public

class

JavaEnumExamples

{ public

static

void

main(

String

[] args) throws IOException { usingEnumMethods(); usingEnumValueOf(); usingEnumValues(); usingEnumInSwitch(ThreadStatesEnum.START); usingEnumInSwitch(ThreadStatesEnum.DEAD); usingEnumMap(); usingEnumSet(); } private

static

void

usingEnumSet() { EnumSet enumSet = EnumSet.allOf(ThreadStatesEnum.class);

for

(ThreadStatesEnum tsenum : enumSet){ System.out.println(

"Using EnumSet, priority = "

+tsenum.getPriority()); } } private

static

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)); } } private

static

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"

); } } private

static

void

usingEnumValues() { ThreadStatesEnum[] thArray = ThreadStatesEnum.values();

for

(ThreadStatesEnum th : thArray){ System.out.println(th.toString() +

"::priority="

+th.getPriority()); } } private

static

void

usingEnumValueOf() { ThreadStatesEnum th = Enum.valueOf(ThreadStatesEnum.class,

"START"

); System.out.println(

"th priority="

+th.getPriority()); } private

static

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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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!!!