2011-01-20 40 views
7

Gần đây, tôi đã nhận thấy, nó có thể có:Trong Java, tại sao nó có thể đủ điều kiện một hằng số Enum với một hằng số Enum khác?

class Test { 
    public enum Season { WINTER, SPRING, SUMMER, FALL } 
    Season field = Season.WINTER.SPRING; // why is WINTER.SPRING possible? 
} 

Có một lý do cho việc này?

+0

Điều đó tương đương với 'WINTER | SPRING'? –

+4

Season.WINTER.SPRING tương đương với Season.SPRING –

+0

Zach L là đúng. –

Trả lời

10

Khi bạn truy cập một thành viên tĩnh của một đối tượng (bao gồm cả enums) trong Java, trình biên dịch thay thế hiệu quả đối tượng bằng loại tĩnh của nó. Cụ thể hơn,

class ExampleClass { 
    static int staticField; 
    static void staticMethod() { 
     ExampleClass example = new ExampleClass(); 
     example.staticField;  // Equivalent to ExampleClass.staticField; 
     example.staticMethod(); // Equivalent to ExampleClass.staticMethod(); 
    } 
} 

Tương tự như vậy, vì sự đếm là một cách hiệu quả "tĩnh", Season.WINTER.SPRING tương đương với Season.SPRING; Season.WINTER được thay thế bằng loại enum Season.

Như một lưu ý phụ, việc truy cập các thành viên tĩnh từ các phiên bản không được khuyến khích vì nó có thể khá khó hiểu. Ví dụ: nếu bạn thấy một đoạn mã có chứa someThread.sleep(), bạn có thể bị lừa tin rằng someThread được đặt vào chế độ ngủ. Tuy nhiên, kể từ khi sleep() là tĩnh, mã đó thực sự gọi Thread.sleep() mà ngủ thread hiện tại.

+0

Tốt , câu trả lời rõ ràng. Cảm ơn. –

+0

Tôi khuyên bạn nên bật cảnh báo cho truy cập tĩnh (Eclipse có tùy chọn này, các IDE khác cũng có thể làm). Tôi luôn luôn sửa những cảnh báo đó vì lý do cụ thể đó: chúng gây nhầm lẫn và có thể đánh lừa bất cứ ai đang đọc mã để nghĩ rằng chương trình đang làm điều gì đó không phải. –

1

Đó là vì enums là loại lớp học đặc biệt. Nếu chúng ta hãy nhìn vào các lĩnh vực bên trong Season.WINTER, ví dụ:

for (Field field : Test.Season.WINTER.getClass().getFields()) 
    System.out.println(field); 

Chúng tôi sẽ thấy như đầu ra:

public static final TestEnum$Test$Season TestEnum$Test$Season.WINTER 
public static final TestEnum$Test$Season TestEnum$Test$Season.SPRING 
public static final TestEnum$Test$Season TestEnum$Test$Season.SUMMER 
public static final TestEnum$Test$Season TestEnum$Test$Season.FALL 

Vì vậy, mỗi giá trị enum là thực sự cũng là một tĩnh liên tục của lớp enum, Season và do đó có quyền truy cập vào các trường tĩnh của Season hoặc các giá trị enum khác (bao gồm cả chính nó).

Tuy nhiên, có thể tốt hơn là chỉ truy cập các giá trị enum trực tiếp từ enum, như Season.SPRING, vì nó đơn giản hơn và ít có khả năng gây nhầm lẫn cho người đọc mã của bạn.

Các vấn đề liên quan