Enums shared static look-up method

匿名 (未验证) 提交于 2019-12-03 01:26:01

问题:

I have the following Enum:

public enum MyEnum{     A(10, "First"), //     B(20, "Second"), //     C(35, "Other options");      private Integer code;     private String description;      private MyEnum(Integer code, String description) {         this.code = code;         this.description = description;     }      public Integer getCode() {         return code;     }      public String getDescription() {         return description;     }      public static MyEnum getValueOf(Integer code) {         for (MyEnum e : MyEnum.values()) {             if (e.getCode().equals(code)) {                 return e;             }         }         throw new IllegalArgumentException("No enum const " + MyEnum.class.getName() + " for code \'" + code                 + "\'");     } } 

Which works fine. The getValueOf-method exists because when communicating with an external partner, we only get the code (they chose) to map to. I need the description because I need to show a meaningfull phrase in the GUI.

But I now have a number of similar enum classes. All having their own code & description, and they need the same lookup functionality. I wanted the getValueOf-method to be generic so I don't need to support 30+ different enums for basically the same method.

To solve this I wanted to make an abstract class to define this method and implement some of the common logic but this is impossible because I can't extend Enum.

Then I tried to make a Utility class with the following method:

public static > T getValueOf(Enum type, Integer code) {...} 

But generics with Enums are confusing and I don't understand how to get this working.

Basically what I want to know is: What is a good approach to define a common utility to an enum?

回答1:

You need to pass the actual enum class object as a parameter to your method. Then you can get the enum values using Class.getEnumConstants().

In order to be able to access getCode() on the instances, you should define it in an interface and make all your enum types implement that interface:

interface Encodable {     Integer getCode(); }  public static  & Encodable> T getValueOf(Class enumClass, Integer code) {     for (T e : enumClass.getEnumConstants()) {         if (e.getCode().equals(code)) {             return e;         }     }     throw new IllegalArgumentException("No enum const " + enumClass.getName() + " for code \'" + code             + "\'"); }  ...  public enum MyEnum implements Encodable {     ... }  MyEnum e = getValueOf(MyEnum.class, 10); 


回答2:

This is a bit tricky because the values() method is static. You would actually need reflection, but there is a nice way to hide this using standard library functionality.

First, define an interface with the methods common to all of your enum types:

public interface Common {     Integer getCode();     String getDescription(); } 

Then, make all your enums implement this interface:

public enum MyEnum implements Common {...} 

The static method you want to have then looks like:

public static  & Common> T getValueOf( Class type, Integer code ) {     final EnumSet values = EnumSet.allOf( type );     for(T e : values) {         if(e.getCode().equals( code )) {             return e;         }     }     throw new IllegalArgumentException( "No enum const " + type.getName() + " for code \'" + code + "\'" ); } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!