2012-12-09 38 views
54

Tôi đang gặp sự cố khi khai báo enum. Những gì tôi đang cố gắng để tạo ra là một enum cho một 'DownloadType', nơi có 3 loại tải về (AUDIO, VIDEO, AUDIO_AND_VIDEO).Java Enum trả về Int

tôi đã thực hiện đoạn code như sau:

private enum DownloadType { 
    AUDIO(0), VIDEO(1), AUDIO_AND_VIDEO(2); 
    private final int value; 

    private DownloadType(int value) { 
     this.value = value; 
    } 
} 

này hoạt động tốt nếu tôi sau đó sử dụng nó như thế này:

DownloadType.AUDIO_AND_VIDEO.value; 

Tuy nhiên, tôi muốn nó vì vậy mà tôi không có để yêu cầu 'giá trị'. Tôi có thể bị nhầm lẫn, nhưng đây là cách một số lớp học làm việc trong Java như Font, ví dụ để thiết lập một kiểu font chữ, bạn sử dụng:

Font.PLAIN 

nào trả về một giá trị int, chúng tôi không sử dụng:

Font.PLAIN.value 
+1

Bạn có thể chỉ cần sử dụng DownloadType.AUDIO_AND_VIDEO cũng trừ khi bạn cần giá trị, tôi có thiếu cái gì không? – kosa

+0

@Nambari Nếu tôi System.out.println (DownloadType.AUDIO_AND_VIDEO) nó trả về "AUDIO_AND_VIDEO" có vẻ như kiểu 'DownloadType', không phải int. – Cristian

+2

Tôi nghĩ rằng bạn đang bối rối với mục đích của enums. Tại sao bạn cần số nguyên? – Jivings

Trả lời

86

Font.PLAINkhông một enum. Nó chỉ là int. Nếu bạn cần lấy giá trị từ một enum, bạn không thể tránh gọi một phương thức hoặc sử dụng một .value, bởi vì enums thực sự là các đối tượng thuộc kiểu riêng của nó, không phải là nguyên thủy.

Nếu bạn thực sự chỉ cần một int, bạn đã chấp nhận rằng kiểu an toàn bị mất người dùng có thể vượt qua các giá trị không hợp lệ để API của bạn, bạn thể xác định những hằng số như int thêm:

static class DownloadType { 
    public static final int AUDIO = 0; 
    public static final int VIDEO = 1; 
    public static final int AUDIO_AND_VIDEO = 2; 
} 

Bằng cách này, các lĩnh vực value thực sự là không cần thiết vì đó cũng là một phương pháp .ordinal(), vì vậy bạn có thể xác định enum như:

enum DownloadType { AUDIO, VIDEO, AUDIO_AND_VIDEO } 

và nhận được "giá trị" sử dụng

DownloadType.AUDIO_AND_VIDEO.ordinal() 
+0

Cảm ơn bạn đã làm rõ, điều này có ý nghĩa ngay bây giờ. Thay vì tạo một enum, tôi sẽ tạo một tệp DownloadType công khai {private static final int AUDIO = 0; } ... Đây có phải là một InnerClass không? Cảm ơn câu trả lời của bạn. – Cristian

+0

@Cristian: Nó chủ yếu phụ thuộc vào cách bạn muốn truy cập nó. – kennytm

+0

Cảm ơn câu trả lời của bạn, chính xác là những gì tôi đang tìm kiếm - chờ 3 phút để chấp nhận – Cristian

38

Nếu bạn cần để có được giá trị int, chỉ cần có một getter cho giá trị trong eNUM của bạn:

private enum DownloadType { 
    AUDIO(1), VIDEO(2), AUDIO_AND_VIDEO(3); 
    private final int value; 

    private DownloadType(int value) { 
     this.value = value; 
    } 

    public int getValue() { 
     return value; 
    } 
} 

public static void main(String[] args) { 
    System.out.println(DownloadType.AUDIO.getValue());   //returns 1 
    System.out.println(DownloadType.VIDEO.getValue());   //returns 2 
    System.out.println(DownloadType.AUDIO_AND_VIDEO.getValue()); //returns 3 
} 

Hoặc bạn có thể sử dụng đơn giản ordinal() phương pháp, trong đó sẽ trở lại vị trí của các enum đồng trong thực tế.

private enum DownloadType { 
    AUDIO(0), VIDEO(1), AUDIO_AND_VIDEO(2); 
    //rest of the code 
} 

System.out.println(DownloadType.AUDIO.ordinal());   //returns 0 
System.out.println(DownloadType.VIDEO.ordinal());   //returns 1 
System.out.println(DownloadType.AUDIO_AND_VIDEO.ordinal()); //returns 2 
+2

Tại sao bạn cần thêm phương thức khi bạn chỉ có thể gọi .value và đã có một phương thức thứ tự() được cung cấp để lấy số nguyên. – kosa

+0

@Nambari umm, dint biết enum có thứ tự .. làm thế nào ngu ngốc của tôi: P – PermGenError

+0

@GanGnaMStYleOverFlowErroR Cảm ơn câu trả lời, nhưng tôi đã thực sự tìm cách để tránh gọi .value, hãy để một mình tạo ra một phương pháp khác và gọi getValue() :) – Cristian

10

Đơn giản chỉ cần gọi phương thức ordinal() trên một giá trị enum, để lấy số tương ứng của nó. Không cần khai báo thuộc tính bổ sung với giá trị của nó, mỗi giá trị được liệt kê sẽ có số riêng của nó theo mặc định, được chỉ định bắt đầu từ số không, tăng thêm một cho mỗi giá trị theo cùng thứ tự mà chúng được khai báo.

Bạn không nên phụ thuộc vào giá trị int của enum, chỉ trên giá trị thực tế của nó. Enums trong Java là một loại khác nhau của quái vật và không giống như enums trong C, nơi bạn phụ thuộc vào mã số nguyên của họ.

Về ví dụ bạn đã cung cấp trong câu hỏi, Font.PLAIN hoạt động vì đó chỉ là hằng số nguyên của lớp Phông chữ.Nếu bạn hoàn toàn cần một mã số (có thể thay đổi), thì enum không phải là công cụ thích hợp cho công việc, tốt hơn nên gắn vào hằng số số.

+1

Tôi biết về thứ tự(), nhưng nếu sau đó tôi muốn thay đổi hoặc chỉ định thứ tự khác trong tương lai, điều này sẽ gây ra sự cố. Tôi muốn chỉ định giá trị int – Cristian

+1

@Cristian bạn không nên phụ thuộc vào giá trị int của một enum, chỉ trên giá trị thực tế của nó. Enums trong Java không giống như enums trong C, nơi bạn phụ thuộc vào mã nguyên của chúng. –

+0

@Cristian và liên quan đến ví dụ bạn đã cung cấp trong câu hỏi 'Font.PLAIN' hoạt động vì đó chỉ là hằng số nguyên của lớp' Phông chữ'. Nếu bạn hoàn toàn cần một mã số (có thể thay đổi), thì một 'enum' không phải là công cụ thích hợp cho công việc, tốt hơn là nên dính vào hằng số. –

3

Nếu bạn đang concatenating enum với một chuỗi bạn có thể ghi đè phương thức toString để trả lại int:

public String toString() { 
    return value + ""; 
} 

Sau đó, bạn chỉ đơn giản là có thể sử dụng:

String something = "foo" + DownloadType.AUDIO; 

và toString() phương pháp sẽ được gọi.

Lưu ý rằng việc sử dụng toString() theo chương trình thường được coi là thực hành kém - chỉ dành cho mắt người, tuy nhiên đây là cách duy nhất để đạt được những gì bạn đang yêu cầu.

+0

Great work-around, cảm ơn! – Cristian

10

Trước tiên, bạn nên tự hỏi mình câu hỏi sau: Bạn có thực sự cần một int không?

Mục đích của enums là có một tập hợp các mục (hằng số), có ý nghĩa trong mã mà không dựa vào giá trị bên ngoài (như int). Enums trong Java có thể được sử dụng như là một đối số trên các stat chuyển đổi và chúng có thể được so sánh một cách an toàn bằng cách sử dụng toán tử "==" (trong số những thứ khác).

Proposal 1 (không int cần thiết):

Thường không có nhu cầu về một số nguyên đằng sau nó.

private enum DownloadType{ 
    AUDIO, VIDEO, AUDIO_AND_VIDEO 
} 

//... 

DownloadType downloadType = MyObj.getDownloadType(); 
if (downloadType == DownloadType.AUDIO) { 
    //... 
} 
//or 
switch (downloadType) { 
    case AUDIO: //... 
      break; 
    case VIDEO: //... 
      break; 
    case AUDIO_AND_VIDEO: //... 
      break; 
} 

Proposal 2 (int cần thiết):

Tuy nhiên đôi khi nó có thể hữu ích để chuyển đổi một enum đến một int (ví dụ nếu một API bên ngoài dự đoán giá trị int). Trong trường hợp này, tôi khuyên bạn nên đánh dấu các phương pháp là phương pháp chuyển đổi bằng cách sử dụng toXxx() -Phong cách. Để in ghi đè toString().

private enum DownloadType { 
    AUDIO(0), VIDEO(1), AUDIO_AND_VIDEO(2); 
    private final int code; 

    private DownloadType(int code) { 
     this.code = code; 
    } 

    public int toInt() { 
     return code; 
    } 

    public String toString() { 
     //only override toString, if the returned value has a meaning for the 
     //human viewing this value 
     return String.valueOf(code); 
    } 
} 

System.out.println(DownloadType.AUDIO);     //returns 0 
System.out.println(DownloadType.AUDIO.name());   //returns AUDIO 
System.out.println(DownloadType.VIDEO.toInt());   //returns 1 
System.out.println(DownloadType.AUDIO_AND_VIDEO.toInt()); //returns 2 

Tóm tắt

  • Không sử dụng một Integer cùng với một enum nếu bạn không phải.
  • Không dựa vào việc sử dụng ordinal() để nhận số nguyên của enum, vì giá trị này có thể thay đổi, nếu bạn thêm hằng số enum khác hoặc thay đổi thứ tự.
  • Thông thường không sử dụng hằng số int thay vì enums (như trong câu trả lời được chấp nhận), bởi vì bạn sẽ mất an toàn kiểu (như @KennyTM đã đề cập).
+0

+1 cho trỏ 'toString()' mặc dù int trở thành một String và tôi sẽ không sử dụng nó vì điều đó :) –

4

Bạn có thể thử mã này.

private enum DownloadType { 
    AUDIO , VIDEO , AUDIO_AND_VIDEO ; 

} 

Bạn có thể sử dụng điều tra này như sau: DownloadType.AUDIO.ordinal(). Hy vọng đoạn mã này sẽ giúp bạn.

3

Bạn có muốn mã này không?

public static enum FieldIndex { 
    HDB_TRX_ID,  //TRX ID 
    HDB_SYS_ID  //SYSTEM ID 
} 

public String print(ArrayList<String> itemName){ 
    return itemName.get(FieldIndex.HDB_TRX_ID.ordinal()); 
} 
Các vấn đề liên quan