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 exist 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?

5 Answers

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;
}
5

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.

1

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;
}
1

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){
       ...
     }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Sarah Jenkins

Sarah Jenkins

Senior Technology Editor & AI Specialist

Sarah Jenkins is a veteran tech journalist with over 12 years of experience covering artificial intelligence, mobile innovations, and digital ethics. Her insights have appeared in leading technology publications worldwide.

Share this article
Twitter Facebook Pinterest