2010-10-21 43 views
77

Tôi hiện đang tạo hằng số nguyên theo cách sau.Lưu trữ các giá trị số nguyên như hằng số theo cách Enum trong java

public class Constants { 
public static int SIGN_CREATE=0; 
public static int SIGN_CREATE=1; 
public static int HOME_SCREEN=2; 
public static int REGISTER_SCREEN=3; 
} 

Khi tôi cố gắng để làm điều này theo cách enum

public enum PAGE{SIGN_CREATE,SIGN_CREATE,HOME_SCREEN,REGISTER_SCREEN} 

và Khi tôi sử dụng PAGE.SIGN_CREATE nó sẽ trả về 1;

+9

Điều đó sẽ không biên dịch; bạn đã xác định "SIGN_CREATE" hai lần. Ngoài ra, đó không phải là hằng số - chúng không phải là "cuối cùng". – BlairHippo

Trả lời

134

Vâng, bạn có thể không hoàn toàn làm điều đó theo cách đó. PAGE.SIGN_CREATE sẽ không bao giờ trả lại 1; nó sẽ trả về PAGE.SIGN_CREATE. Đó là điểm của các loại liệt kê.

Tuy nhiên, nếu bạn sẵn sàng thêm một vài tổ hợp phím, bạn có thể thêm các trường để enums của bạn, như thế này:


    public enum PAGE{ 
     SIGN_CREATE(0), 
     SIGN_CREATE_BONUS(1), 
     HOME_SCREEN(2), 
     REGISTER_SCREEN(3); 

     private final int value; 

     PAGE(final int newValue) { 
      value = newValue; 
     } 

     public int getValue() { return value; } 
    } 

Và sau đó bạn gọi PAGE.SIGN_CREATE.getValue() để có được 0.

+7

Điều này thực sự không đúng. Bạn có thể làm PAGE.SIGN_CREATE.ordinal(). Điều này sẽ trả lại 0. Có lẽ anwser này có liên quan đến một phiên bản java, chưa có tính năng này. – TheTrowser

+1

Bạn muốn kết hợp số và ký tự trong một enum đơn lẻ? Ví dụ. nếu tôi muốn một enum để lưu trữ 0, 1 và X? Cảm ơn bạn!! – russellhoff

+1

@BlairHippo: Tôi có thể làm điều gì đó như 'PAGE pageEnum = PAGE (0)'. Nói một cách đơn giản, tôi có một giá trị với tôi và tôi muốn có được enum tương ứng với giá trị đã chọn. Bạn có thể trả lời? –

13

Bạn có thể sử dụng ordinal. Vì vậy, PAGE.SIGN_CREATE.ordinal() trả về 1.

EDIT:

Vấn đề duy nhất với việc này là nếu bạn thêm, xóa hoặc sắp xếp lại các giá trị enum bạn sẽ phá vỡ hệ thống. Đối với nhiều người, đây không phải là vấn đề vì họ sẽ không loại bỏ enums và sẽ chỉ thêm các giá trị bổ sung vào cuối. Nó cũng không tệ hơn các hằng số nguyên cũng yêu cầu bạn không phải đổi lại chúng. Tuy nhiên, tốt nhất là sử dụng hệ thống như:

public enum PAGE{ 
    SIGN_CREATE0(0), SIGN_CREATE(1) ,HOME_SCREEN(2), REGISTER_SCREEN(3) 

    private int id; 

    PAGE(int id){ 
    this.id = id; 
    } 

    public int getID(){ 
    return id; 
    } 

} 

Sau đó, bạn có thể sử dụng getID. Vì vậy, PAGE.SIGN_CREATE.getID() trả lại 1.

+1

Mặc dù ý tưởng tồi, vì nó sẽ thay đổi khi thứ tự của các hằng số trong khai báo lớp thay đổi. –

+0

@Michael - Đó là một điểm tốt. Tôi đã thêm một phương pháp bổ sung để tránh vấn đề đó. – Adam

2

Bạn có thể lưu trữ giá trị const đó trong enum như vậy. Nhưng tại sao lại sử dụng const? Bạn có kiên trì của enum?

public class SO3990319 { 
    public static enum PAGE { 
     SIGN_CREATE(1); 
     private final int constValue; 

     private PAGE(int constValue) { 
     this.constValue = constValue; 
     } 

     public int constValue() { 
     return constValue; 
     } 
    } 

    public static void main(String[] args) { 
     System.out.println("Name: " + PAGE.SIGN_CREATE.name()); 
     System.out.println("Ordinal: " + PAGE.SIGN_CREATE.ordinal()); 
     System.out.println("Const: " + PAGE.SIGN_CREATE.constValue()); 

     System.out.println("Enum: " + PAGE.valueOf("SIGN_CREATE")); 
    } 
} 

Edit:

Nó phụ thuộc vào những gì bạn đang sử dụng int cho dù sử dụng EnumMap hoặc trường ví dụ.

+0

Tôi đang đối mặt với vấn đề mà tôi không thể vượt qua giá trị enum để chuyển đổi trường hợp! "case Actions.CREATE.getAction()" nó đưa ra một lỗi "biểu thức trường hợp phải là biểu thức hằng số" –

+1

Actions.CREATE là enum. #getAction() không phải là ... – TJR

18

Nhất lý do hợp lệ chung để muốn hằng số nguyên được kết hợp với mỗi giá trị enum là tương thích với một số thành phần khác mà vẫn mong đợi các số nguyên đó (ví dụ: giao thức tuần tự hóa mà bạn không thể thay đổi, hoặc enums đại diện cho các cột trong bảng, vv).

Trong hầu hết các trường hợp, tôi khuyên bạn nên sử dụng EnumMap để thay thế. Nó tách rời các thành phần hoàn toàn hơn, nếu đó là mối quan tâm, hoặc nếu enums đại diện cho các chỉ mục cột hoặc một cái gì đó tương tự, bạn có thể dễ dàng thay đổi sau này (hoặc ngay cả khi chạy nếu cần).

private final EnumMap<Page, Integer> pageIndexes = new EnumMap<Page, Integer>(Page.class); 
pageIndexes.put(Page.SIGN_CREATE, 1); 
//etc., ... 

int createIndex = pageIndexes.get(Page.SIGN_CREATE); 

Nó thường cực kỳ hiệu quả.

Việc thêm dữ liệu như thế này vào bản thân enum có thể rất mạnh, nhưng thường xuyên hơn là không bị lạm dụng.

Edit: Chỉ cần nhận ra Bloch quyết này trong Effective Java/2nd edition, trong mục 33: Sử dụng EnumMap thay vì chỉ mục thứ.

+0

+1 trên đề xuất EnumMap. – I82Much

+1

Điều đó cũng khá dài dòng. Nó có nghĩa là bạn giữ một cấu trúc dữ liệu hoàn toàn riêng biệt chỉ để có một ánh xạ từ khóa đến một chỉ số số có nguồn gốc. Bloch cũng (mục 31) gợi ý cho các giá trị chỉ số nguyên đơn giản để sử dụng mẫu được nêu trong câu trả lời của @ BlairHippo cho câu hỏi này. –

0

nếu bạn muốn để có thể chuyển đổi integer trở lại tương ứng enum với giá trị được chọn thấy Constants.forValue(...) ở bên dưới tự động tạo mã nhưng nếu không phải là câu trả lời của BlairHippo là cách tốt nhất để làm điều đó.

public enum Constants 
{ 
SIGN_CREATE(0), 
SIGN_CREATE(1), 
HOME_SCREEN(2), 
REGISTER_SCREEN(3); 

    public static final int SIZE = java.lang.Integer.SIZE; 

    private int intValue; 
    private static java.util.HashMap<Integer, Constants> mappings; 
    private static java.util.HashMap<Integer, Constants> getMappings() 
    { 
     if (mappings == null) 
     { 
      synchronized (Constants.class) 
      { 
       if (mappings == null) 
       { 
        mappings = new java.util.HashMap<Integer, Constants>(); 
       } 
      } 
     } 
     return mappings; 
    } 

    private Constants(int value) 
    { 
     intValue = value; 
     getMappings().put(value, this); 
    } 

    public int getValue() 
    { 
     return intValue; 
    } 

    public static Constants forValue(int value) 
    { 
     return getMappings().get(value); 
    } 
} 
0

Tôi thấy điều này trở nên hữu ích:

http://dan.clarke.name/2011/07/enum-in-java-with-int-conversion/

public enum Difficulty 
{ 
    EASY(0), 
    MEDIUM(1), 
    HARD(2); 

    /** 
    * Value for this difficulty 
    */ 
    public final int Value; 

    private Difficulty(int value) 
    { 
     Value = value; 
    } 

    // Mapping difficulty to difficulty id 
    private static final Map<Integer, Difficulty> _map = new HashMap<Integer, Difficulty>(); 
    static 
    { 
     for (Difficulty difficulty : Difficulty.values()) 
      _map.put(difficulty.Value, difficulty); 
    } 

    /** 
    * Get difficulty from value 
    * @param value Value 
    * @return Difficulty 
    */ 
    public static Difficulty from(int value) 
    { 
     return _map.get(value); 
    } 
} 
Các vấn đề liên quan