2011-12-11 26 views
12

Hãy nói rằng tôi có một tập tin có định dạng là XML cơ bản, như vậy:Tạo Enums động

<?xml version="1.0"?> 
<enum-set> 
    <enum> 
     <name>SomeEnum</name> 
     <values> 
      <value> 
       <name>SOMEVALUE</name> 
       <displayText>This is some value</displayText> 
      </value> 
      ... more values ... 
     </values> 
    </enum> 
    ... more enums ... 
</enum-set> 

và tôi muốn biến SomeEnum vào một cái gì đó như thế này trong thời gian chạy:

public enum SomeEnum implements HasDisplayText { 
    SOMEVALUE("This is some value"), 
    ... more values ...; 

    private String displayText; 

    SomeEnum(String displayText) { 
     this.displayText = displayText; 
    } 

    @Override 
    public String getDisplayText() { 
     return displayText; 
    } 
} 

.. và sau đó chuyển enum mới được tạo ra SomeEnum xung quanh ứng dụng của tôi. Làm thế nào tôi có thể đạt được một cái gì đó như thế này? Nó có thể làm được không?

Trả lời

14

Điều bạn đang cố gắng làm không có ý nghĩa gì cả. Enums thực sự chỉ vì lợi ích của thời gian biên dịch, vì chúng đại diện cho một tập hợp các hằng số cố định. Khi chạy, ý nghĩa của một enum được tạo động - điều này sẽ khác với một đối tượng đơn giản như thế nào? Ví dụ:

public class Salutation implements HasDisplayText { 

    private String displayText; 

    private Salutation(String displayText) { 
     this.displayText = displayText; 
    } 

    @Override 
    public String getDisplayText() { 
     return displayText; 
    } 

    public static Collection<Salutation> loadSalutations(String xml) { 
     //parse, instantiate, and return Salutations 
    } 
} 

XML của bạn có thể được phân tích thành mới được khởi tạo Salutation đối tượng, mà có thể được lưu trữ trong một số Collection hoặc sử dụng bởi chương trình của bạn. Lưu ý trong ví dụ của tôi, tôi đã hạn chế việc tạo ra Salutation bằng cách cho nó một hàm tạo private - trong trường hợp này, cách duy nhất để truy xuất các cá thể là gọi phương thức factory lấy XML của bạn. Tôi tin rằng điều này đạt được hành vi mà bạn đang tìm kiếm.

+0

Làm cho tinh thần. Tôi hỏi về enums đặc biệt bởi vì hệ thống phân cấp của tôi có quá nhiều thứ trong số họ bây giờ (không phải là một số tiền vô lý, chỉ hơn một vài) và tôi đã hy vọng loại bỏ chúng. –

+0

@Chris - Đợi đã, vậy câu hỏi của bạn về tạo mã hoặc tạo chúng khi chạy là gì? –

+0

Thực sự đó là về việc tạo chúng khi chạy. Tôi cho rằng đó là khác nhau. –

6

Trên thực tế, có thể tạo các trường hợp enum động, nhưng đó là tổng số hack, tôi sẽ không tư vấn gì cả - có thể bạn đang hiểu nhầm bản chất của một enum, đó là tính năng biên dịch của ngôn ngữ và bạn không được phép thêm/xóa các phiên bản khỏi nó khi chạy.

Dù sao, nếu bạn quan tâm đến việc hack để tạo các trường hợp enum động, hãy xem article này.

0

Đồng ý với Oscar Lopez. Đây là những gì tôi đã làm, một loại hack.

public static enum Setter { 

    DYNAMIC_ENUM_EXAMPLE { 

     @Override 
     public String setGetValue(String yourValue) { 
      return "prefix " + yourValue + " postfix"; 
     } 
    }; 
    public abstract String setGetValue(String value); 
} 

Bạn có thể nhận được giá trị như thế này:

Setter.DYNAMIC_ENUM_EXAMPLE.setGetValue("namaste") 

Output:

prefix namaste postfix 
0

động Enums là câu trả lời cho vấn đề của bạn:

public abstract class DEnum<E extends DEnum<E>> implements Comparable<E>, Serializable { 

Lớp này có chữ ký tương tự như tiêu chuẩn Enu lớp m. Nó có một constructor được bảo vệ để cho phép tạo instance trong các lớp Enum cụ thể.Ví dụ:

public class YesNo extends DEnum<YesNo> { 

    public final static YesNo YES = new YesNo(); 
    public final static YesNo NO = new YesNo(); 

Lớp DEnum biết tên của các thành viên bằng cách mẫn:

String name = YesNo.YES.getName(); 
YesNo yes = YesNo.get(YesNo.class, name); 
assert (yes == YesNo.YES); 

Có một getter gõ để lấy tất cả các mục:

YesNo[] items = yes.getItems(); 
assert (items.length == 2); 

Nó cho phép thêm thành viên động vào thời gian chạy với (từ cơ sở dữ liệu hoặc từ tệp):

YesNo maybe = getOrCreateIfNotExists(YesNo.class, "MAYBE"); 
items = yes.getItems(); 
assert (items.length == 3); 

Có hành vi tương tự như các thành viên tĩnh:

YesNo unknown = YesNo.get(YesNo.class, "MAYBE"); 
assert (unknown == maybe); 
+0

Bạn nên bao gồm một liên kết để thực hiện 'DEnum' hoặc đăng nó ở đây –