开发者

How do I reimplement valueof on enumeration

I need to re-implement the enum.valueof method of a few of my enumerations so they no longer throw exceptions, instead they simply return null if a value doesn't e开发者_开发问答xist in the enumeration.

I'm trying the basic

@Override
    public static <T extends Enum<T>> T valueOf(Class<T> enumType,
            String name){

but it's not working, saying I need to override or implement a super type.

I can come up with a super class I guess, but I'm just not sure how to put this together. Any ideas?


You can't. You'll have to define another, different method. The valueOf method is automatically generated by the compiler.

public static MyEnum permissiveValueOf(String name) {
    for (MyEnum e : values()) {
        if (e.name().equals(name)) {
            return e;
        }
    }
    return null;
}


Use Apache Commons Lang:

MyEnum myEnum = EnumUtils.getEnum(MyEnum.class, "MY_ENUM_VALUE");

Quote from the Javadoc for EnumUtils.getEnum:

Gets the enum for the class, returning null if not found.

This method differs from Enum.valueOf(java.lang.Class, java.lang.String) in that it does not throw an exception for an invalid enum name.


Is it absolutely necessary that the method is called valueOf like the method that enums have automatically? In the project that I'm currently working on we have similar methods, but we call them differently; for example, forName:

public static ESomeEnum forName(String name) {
    for (ESomeEnum e : ESomeEnum.values()) {
        if (e.name().equals(name)) {
            return e;
        }
    }

    return null;
}


You don't have to override valueOf. Here's what I did:

I had to "parse" some strings to enums and they didn't match with their declaration names, so I did a sort of reimplementation of valueOf(String name).

public enum Command {
    DIR("DIR"),
    PUT("PUT"),
    GET("GET"),
    OK("OK"),
    ERROR("ERROR"),
    READY("READY"),
    FIN("#FIN#");

    private String name;

    private Command(final String name) {
        this.name = name;
    }

    /**
     * Returns the desired Enum or throws an exception
     * @param commandName - String with the name contained by the Enum that you want
     * @return Command
     */
    public static Command getEnum(String commandName){
        // if the string is "#FIN#" returns Command.FIN.
        if(FIN.toString().equals(commandName)){
            return FIN;
        }
        // if the name matches any of the remaining enums return whichever one matches
        else if(Arrays.asList(Command.values()).contains(Command.valueOf(commandName))){
            return Command.valueOf(commandName);
        }
        // if it still wasn't found, throw an exception
        throw new IllegalArgumentException("No enum defined for this string: " + commandName);
    }

    @Override
    public String toString(){
            return name;
        }
    }

This code is tested and works.

You can use like:

Command k = Command.getEnum("#FIN#");
System.out.println(k.name() + "  " +k.toString());
k = Command.getEnum("PUT");
System.out.println(k.name() + "  " +k.toString());

And it's output would be:

FIN  #FIN#
PUT  PUT

Hope it helps.


You might consider creating a new (different name such as convert) static method in your enum classes.

public enum MyEnum{
      ....

     public static MyEnum convert(Object value){
       ...
     }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜