2010-09-29 34 views
88

Tôi có một enum SOME_ENUM:enum.values ​​() - là một thứ tự enums trở xác định

public enum SOME_ENUM { 
    EN_ONE, 
    EN_TWO, 
    EN_THREE; 
} 

Will SOME_ENUM.values() luôn trả lại sự đếm theo thứ tự của tờ khai enum: EN_ONE, EN_TWO, EN_THREE? Nó là một quy tắc hoặc nó không được đảm bảo không được thay đổi trong các bản phát hành JDK tiếp theo?

+1

tại sao bạn sẽ dựa vào nó? –

+1

Tôi lặp lại trên enum của tôi để điền vào một danh sách, mà hơn ở nơi khác trong mã tôi đọc lặp đi lặp lại trong enum này. – Skarab

+11

@MitchWheat Vì lý do tương tự mà bạn sẽ dựa vào một thứ tự lưu giữ danh sách: vì JDK là một công cụ cung cấp cho bạn một số đảm bảo và dựa vào những đảm bảo này giúp bạn viết mã ngắn gọn và tốt hơn. Phải thừa nhận rằng, câu hỏi "Có đảm bảo không được thay đổi?" không thể trả lời, bạn chắc chắn không thể dựa vào điều đó, không có gì đảm bảo điều đó. – Fletch

Trả lời

126

Đặc tả ngôn ngữ Java sử dụng ngôn ngữ rõ ràng này:

@return một mảng chứa các hằng số kiểu enum này, theo thứ tự chúng được khai báo [Source]

Vì vậy, vâng , họ sẽ được trả lại theo thứ tự khai báo. Cần lưu ý rằng thứ tự có thể thay đổi theo thời gian nếu ai đó thay đổi lớp học vì vậy hãy cẩn thận về cách bạn sử dụng nó.

+1

Nếu ai đó thêm một giá trị ở giữa trong một phiên bản mã sau, điều này có thể giúp bạn tăng tốc, vì nó sẽ thay đổi giá trị thứ tự của các phần tử khác (xem phương thức Enum.ordinal()). Tốt nhất là không nên dựa vào vị trí thứ tự như một cơ chế tuần tự hóa (ví dụ, không lưu trữ nó trong db) vì lý do này. – Matt

+1

Liên kết với nguồn cho đặc tả đó? – screenmutt

+0

[Java 8 doc] (http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3) –

14

Có, nó được đảm bảo trả lại chúng theo thứ tự đó.

Tuy nhiên, bạn nên tránh dựa vào điều đó và trên giá trị ordinal(), vì nó có thể thay đổi sau khi chèn các mục mới, chẳng hạn.

+0

+1 cho lời khuyên hiền triết.Về chủ đề của thứ tự(), Java hiệu quả đề xuất thêm một trường thành viên vào kiểu enum. – ide

9

Được xác định theo thứ tự giá trị của bạn được khai báo. Tuy nhiên, không đảm bảo rằng bạn (hoặc người nào khác) sẽ không sắp xếp lại/chèn/xóa các giá trị trong tương lai. Vì vậy, bạn không nên dựa vào thứ tự.

Hiệu quả Java thứ 2. Phiên bản dành mục của nó 31 đến một chủ đề liên quan chặt chẽ: Sử dụng instance fields thay vì ordinals:

Không bao giờ lấy được một giá trị gắn liền với một enum từ thứ tự của nó; lưu trữ nó trong một trường thể hiện để thay thế.

+3

"không đảm bảo rằng ai đó sẽ không sắp xếp lại các giá trị trong tương lai" - nhưng đó chính xác là lý do tôi muốn dựa vào thứ tự :-)! Tôi muốn có thể sắp xếp lại các mục trong tương lai và do đó thay đổi hành vi của chương trình của tôi. Bloch là đúng về việc không dựa vào thứ tự và nếu ví dụ của người hỏi thực sự liên quan đến enums như EN_TWO sau đó ông là dựa vào thứ tự và không nên làm điều này. Nhưng để dựa vào thứ tự là hoàn toàn tốt đẹp. Trong thực tế, theo thứ tự được đảm bảo, để tạo ra một lĩnh vực đặc biệt cho đơn đặt hàng sẽ được viết mã dư thừa, các loại sách điều như hiệu quả Java cho bạn biết không làm. – Fletch

+0

@Fletch, xin lỗi, tôi không thực sự theo bạn. Với tôi điều này nghe có vẻ như bạn đang cố gắng sử dụng 'enum' cho một số mục đích nó không được dự định. –

+0

giả sử bạn có enum "Planet" nổi tiếng. Trong giao diện người dùng của bạn, bạn muốn liệt kê các hành tinh theo thứ tự khoảng cách của chúng từ mặt trời. Làm thế nào bạn có thể đạt được điều này tốt nhất? Tôi sẽ ra lệnh cho các hằng số hành tinh theo đúng thứ tự bên trong lớp enum và sau đó chỉ liệt kê enum trong giao diện người dùng. Kể từ khi đơn đặt hàng là đáng tin cậy này sẽ làm việc. Đó là điều tôi đang nói đến. Nếu một ngày nào đó trái đất di chuyển gần mặt trời hơn sao Hỏa, tất nhiên trong một khoảnh khắc như vậy điều đầu tiên trên tâm trí ấm áp của bạn sẽ được duy trì mã của bạn! Vì vậy, bạn vào lớp Planet của bạn và di chuyển EARTH đến trước MARS. – Fletch

7

Những câu trả lời khác là tốt, nhưng tôi không bình luận về vấn đề này: "Có một quy tắc hoặc nó không được bảo đảm đến được không thay đổi trong JDK tiếp theo phát hành"

Tôi không tin rằng đảm bảo về các JDK trong tương lai tồn tại, vì vậy bạn thậm chí không nên lo lắng về chúng. Sẽ không có cách nào để thực thi chúng, các khách hàng tiềm năng JDK trong tương lai có thể quyết định từ bỏ những bảo đảm đó. Nó giống như hệ thống quốc hội Westminster: "Không Quốc hội nào có thể ràng buộc một quốc hội tương lai."

Điều đó nói rằng, lịch sử của JDK cho thấy sự nhất quán tuyệt vời. Chúng không tạo ra nhiều thay đổi, do đó bạn có thể tự tin rằng hành vi được chỉ định được chỉ định hiện tại (không chỉ quan sát) sẽ được giữ nguyên.

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