Làm thế nào để chuyển đổi giá trị enum thành int?


240

Tôi có một hàm trả về một kiểu int. Tuy nhiên, tôi chỉ có một giá trị của bảng liệt kê thuế.

Làm cách nào tôi có thể truyền giá trị liệt kê TAX cho int?

public enum TAX {
    NOTAX(0),SALESTAX(10),IMPORTEDTAX(5);

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

TAX var = TAX.NOTAX; // This value will differ

public int getTaxValue()
{
  // what do do here?
  // return (int)var;
}

1
Bản sao có thể có của Cách khớp int với enum
malat

Câu trả lời:


354

Bạn cần phải làm cho enum lộ ra valuebằng cách nào đó, vd

public enum Tax {
    NONE(0), SALES(10), IMPORT(5);

    private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

...

public int getTaxValue() {
    Tax tax = Tax.NONE; // Or whatever
    return tax.getValue();
}

(Tôi đã thay đổi tên thành một chút thông thường và dễ đọc hơn, btw.)

Điều này là giả sử bạn muốn giá trị được gán trong hàm tạo. Nếu đó không phải là điều bạn muốn, bạn sẽ cần cung cấp cho chúng tôi thêm thông tin.


1
@likejiujitsu: Điều đó đi theo hướng ngược lại. Trong câu hỏi này, OP đã một giá trị loại Taxvà muốn lấy giá trị số từ nó.
Jon Skeet

Tôi vừa thử nó và nhận ra nó không thành công, myEnumValue = MyEnum.valueOf(myInt);loại arg phải là loại String - hoặc có thiếu thứ gì không?
likejudo

Giải pháp này còn tệ hơn là không có gì. Có vẻ như enums trong Java không nên được sử dụng? Hay JDK 1.8 đã thay đổi điều đó?
ebyrob

@itherrob: Đưa ra biểu quyết, có vẻ như nhiều người không đồng ý với bạn, như tôi làm. Nếu bạn muốn có một bộ giá trị cố định, enums hoàn toàn tốt.
Jon Skeet

209

Tôi thích điều này:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

sau đó:

//cast enum to int
int color = Color.Blue.ordinal();

34
Điều này không chính xác / không được Joshua Bloch khuyến nghị trong cuốn sách Java hiệu quả (tái bản lần 2). Xem mục 31.
user504342

43
@ user504342 Tôi không có phiên bản thứ 2 của cuốn sách vì vậy bạn có thể vui lòng cho chúng tôi biết lý do tại sao nó không được đề xuất không?
likejudo

17
2 lý do: một, bất kỳ mối liên hệ nào giữa các giá trị thứ tự và các hằng số sẽ bị phá vỡ nếu các hằng số mới được thêm vào và hai tài liệu API đặc biệt khuyến nghị chống lại nó.
jordanpg

8
Thật sạch sẽ và hoàn hảo. Tôi thấy một số "không làm" và "không được đề xuất". Tôi sẽ phải nghiên cứu về lý do tại sao nó được coi là xấu. Một số mẫu cồng kềnh trông xấu IMO. Quá nhiều công việc để làm một nhiệm vụ đơn giản như vậy.
Herb Meehan

4
Trong một nhóm, bạn khá chắc chắn về nhà đồng phát triển của mình sẽ thêm một giá trị ở giữa (tệ hơn lúc đầu) hoặc chỉ sắp xếp chúng vì chúng không có gì để làm và hoàn toàn làm rối mã bằng cách sử dụng.ordinal()
Michael Laffargue

18

Nếu bạn muốn giá trị bạn đang gán trong hàm tạo, bạn cần thêm một phương thức trong định nghĩa enum để trả về giá trị đó.

Nếu bạn muốn một số duy nhất đại diện cho giá trị enum, bạn có thể sử dụng ordinal().


2
Hãy cẩn thận. Có nhiều kiểu chống phát triển dựa vào ordinal()hơn các trường hợp sử dụng hợp lệ cho ordinal(). Nếu bạn cần lưu trữ một giá trị duy nhất cho enum, thì chỉ cần lưu trữ enum. Có EnumSets, Danh sách Enums, EnumMaps và gần như bất kỳ bộ sưu tập Enum nào khác mà bạn có thể muốn có sẵn.
Edwin Buck

1
@EdwinBuck: Thật tốt khi chỉ ra, tôi chỉ muốn đề cập đến sự tồn tại của ordinal()vì OP không nói rõ anh ấy muốn int thực sự là gì.
unolysampler

Đừng nhận chức. Vui lòng kiểm tra api enum liên quan đến điều này. Bỏ phiếu bỏ.
Hovercraft Full Of Eels

3
Tôi tự hỏi suy nghĩ của mọi người về việc sử dụng ordinal()nội bộ trong chính enum. Ví dụ, nói rằng tôi có một enum gọi là " Season", trong đó có các giá trị Spring, Summer, Autumn, và Winter, và nó có một phương pháp nào gọi là next()trả về values()[(ordinal() + 1) % 4] bên ngoài, không có mã bao giờ nhìn thấy số thứ tự, và sẽ không bao giờ được bổ sung thành viên trong enum này, vì vậy nó có vẻ như là một trường hợp sử dụng hợp lệ.
Darrel Hoffman

1
@DarrelHoffman Cảm giác của tôi là làm điều đó là tốt, vì những lý lẽ mạnh mẽ duy nhất tôi thấy chống lại việc sử dụng ordinal()bản lề trên mã xa bị phá vỡ bởi những thay đổi đối với hằng số liệt kê. Nếu bạn định sửa đổi các hằng số của enum, bạn phải có trong tệp đó. Hầu hết các enum đều khá ngắn và nếu không, bạn vẫn nên kiểm tra tệp kỹ lưỡng hơn. Trong cả hai trường hợp, có lẽ bạn nên có một bài kiểm tra đơn vị bao gồm next()phương pháp của bạn .
Alan Hensley

12

Đôi khi một số cách tiếp cận C # làm cho cuộc sống dễ dàng hơn trong thế giới Java ..:

class XLINK {
static final short PAYLOAD = 102, ACK = 103, PAYLOAD_AND_ACK = 104;
}
//Now is trivial to use it like a C# enum:
int rcv = XLINK.ACK;

Đối với tôi đây là cách tốt nhất để đi. Tôi nhận được những lợi ích của enum (mã rõ ràng), một kiểu dữ liệu thân thiện với DB và tôi không phải nghiên cứu 100 phương án enum để thực hiện theo cách "android". Đơn giản và hiệu quả.
John Ward

Đẹp. Như thể java enum hoàn toàn bị ngắt kết nối với thực tế của một enum được sử dụng cho ... đặc biệt là nếu mọi người sau đó bắt đầu lạm dụng nó cho những thứ như singletons. Cách tiếp cận này có nhược điểm là nó không có cách dễ dàng để có được tất cả các giá trị.
Nyerguds

Điều này có bất lợi gì khi cố gắng truyền giá trị enum cho một phương thức không? Bạn không còn có thể truyền XLINK cho một phương thức, bởi vì nó không đại diện cho bất cứ điều gì cụ thể. Bạn mất việc gõ vào phương pháp của bạn. Chữ ký phương thức sẽ phải đọc ngắn thay vì XLINK.
Dustin Jensen

2

Có lẽ tốt hơn là sử dụng biểu diễn Chuỗi hơn số nguyên, vì Chuỗi vẫn hợp lệ nếu các giá trị được thêm vào enum. Bạn có thể sử dụng phương thức name () của enum để chuyển đổi giá trị enum thành Chuỗi, phương thức valueOf () của enum để tạo lại biểu diễn enum từ Chuỗi. Ví dụ sau đây cho thấy cách chuyển đổi giá trị enum thành Chuỗi và ngược lại (ValueType là một enum):

ValueType expected = ValueType.FLOAT;
String value = expected.name();

System.out.println("Name value: " + value);

ValueType actual = ValueType.valueOf(value);

if(expected.equals(actual)) System.out.println("Values are equal");

1
public enum Tax {

NONE(1), SALES(2), IMPORT(3);

private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public String toString() {
        return Integer.toString(value);
    }
}

class Test {
    System.out.println(Tax.NONE);    //Just an example.
}

0

Một cách tiếp cận hơi khác (ít nhất là trên Android) là sử dụng chú thích IntDef để kết hợp một bộ hằng số int

@IntDef({NOTAX, SALESTAX, IMPORTEDTAX})
@interface TAX {}
int NOTAX = 0;
int SALESTAX = 10;
int IMPORTEDTAX = 5;

Sử dụng làm tham số hàm:

void computeTax(@TAX int taxPercentage){...} 

hoặc trong một khai báo biến:

@TAX int currentTax = IMPORTEDTAX;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.