Please rethink extended enums inclusion

Rémi Forax forax at univ-mlv.fr
Fri Oct 7 09:16:08 PDT 2011


I think this should work:

public interface EnumCode {
   public String getCode();
}

public class EnumCodes {
   private static final ClassValue<HashMap<String, EnumCode>> 
ENUM_CODE_MAP =
       new ClassValue<HashMap<String, EnumCode>>() {
         @Override
         protected HashMap<String, EnumCode> computeValue(Class<?> type) {
           HashMap<String, EnumCode> map = new HashMap<>();
           Object[] enumConstants=type.getEnumConstants();
           if (enumConstants == null) {
             return null;
           }
           EnumCode[] enumCodes = (EnumCode[]) enumConstants;
           for(EnumCode enumCode: enumCodes) {
             map.put(enumCode.getCode(), enumCode);
           }
           return map;
         }
       };

    public static <E extends Enum<E> & EnumCode> E getEnum(String code, 
Class<E> enumType) {
      HashMap<String, EnumCode> map = ENUM_CODE_MAP.get(enumType);
      if (map == null) {
        throw new AssertionError("not an enum code");
      }
      EnumCode enumCode = map.get(code);
      if (enumCode == null) {
        throw new IllegalArgumentException("invalid code "+code+" for 
enum type "+enumType.getName());
      }
      return enumType.cast(enumCode);
    }
}

so your enums are coded like that:

public enum EnumCodeFoo implements EnumCode {
   A("1"),
   B("456"),
   C("788999");

   private final String code;

   private EnumCodeFoo(String code) {
     this.code = code;
   }

   @Override
   public String getCode() {
     return code;
   }
}

and you can use EnumCodes like this:
   EnumCodeFoo enumCodeFoo = EnumCodes.getEnum("788999", EnumCodeFoo.class);
   System.out.println(enumCodeFoo);

basically you encode the association enum -> code in the enum and you 
use a ClassValue
and a HashMap to store the association class -> code -> enum.

cheers,
Rémi

On 10/07/2011 05:35 PM, Jose Antonio Illescas Del Olmo wrote:
> On 07/10/2011 17:24, Henri Gerrits wrote:
>> From: Jose Antonio Illescas Del Olmo<jantonio.illescas at rbcdexia-is.es>
>>> To: Henri Gerrits<henrigerrits at yahoo.com>
>>> Cc: "coin-dev at openjdk.java.net"<coin-dev at openjdk.java.net>
>>> Sent: Friday, October 7, 2011 9:18 AM
>>> Subject: Re: Please rethink extended enums inclusion
>>>
>>>
>>> On 07/10/2011 14:32, Henri Gerrits wrote:
>>> Hi Jose Antonio,
>>>>
>>>> I have some issues with your proposal:
>>>>
>>>> 1. Inserting a superclass with new methods might break many existing enums
>>> Why? I decide when extends from custom abstract enum (checking that works fine) other enums (extends from "standard" enum) and works as ever.
>>
>> I misunderstood - my mistake.
>>
>>> 2. Why do you need a code field? The name() method already returns a unique value.  The static valueOf() method can then be used instead of your fromCode() method.  I don't think caching makes much sense with enums, since the number of possible values are usually fairly small
>>>
>>> We have many communications with other finantial entities that use "standard protocols" with custom codes, while our application use descriptive enum names (on enums maps this relation between enums and codes).
>>>
>>> Our enums can parse from "standard codes" to enums and viceversa.
>>
>> OK.  I don't know the details of your application but you might want to decouple the external protocol codes from your business code.  Maybe you can add simple "translator" classes used only in your interfaces with the external entities.
>>
> The enum is my "translator",
>
>      · On some cases/enums I persist the code on database: our "new
> application" accesss to legacy tables used by other applications, and
> persists the enum code
>
>
>>>>> /Abstract enums with Generic support reduce dramatically the code of
>>>>> enums, see next code that use abstract enums:
>>>>> /
>>>>> *public enum Type extends MyAbstractEnum<String>   {
>>>>>
>>>>>         ONE("01), TWO("03"), THREE("03"), ...;
>>>>>
>>>>>         private Type(String code) {
>>>>>             super(code);
>>>>>         }
>>>>>     }*
>>>>>
>>
>> I think that should read:
>>
>>     public enum Type extends MyAbstractEnum<String, Type>   {
>>
>> because you need the subclass type ("Type") for the in() method in MyAbstractEnum.
>>
> You are right.
>
>
>> Best regards,
>>
>> Henri
>>
>




More information about the coin-dev mailing list