Как переопределить valueof в перечислении

Мне нужно повторно реализовать перечисление.valueof метод нескольких моих перечислений, чтобы они больше не бросали исключения, вместо этого они просто возвращают null, если значение не существует в перечислении.

Я пробую basic

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

но это не работает, говорю, что мне нужно переопределить или реализовать супер тип.

Я могу придумать супер класс, я думаю, но я просто не уверен, как это собрать. Есть идеи?

5 ответов


вы не можете. Вам придется определить другой, другой метод. Метод valueOf автоматически генерируется компилятором.

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

Используйте Apache Commons Lang:

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

цитата javadoc для EnumUtils.getEnum:

получает перечисление для класса, возвращая null если не найдено.

этот метод отличается от перечисления.метод valueOf(Ява.ленг.Класс, Ява.ленг.String) в том, что он не создает исключение для недопустимое имя перечисления.


абсолютно необходимо, чтобы метод назывался valueOf как метод перечисления автоматически? В проекте, над которым я сейчас работаю, у нас есть похожие методы, но мы называем их по-разному; например, forName:

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

    return null;
}

вам не нужно переопределять valueOf. Вот что я сделал:--5-->

мне пришлось "разобрать" некоторые строки для перечислений, и они не совпадали с их именами объявлений, поэтому я сделал своего рода повторное выражение 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;
        }
    }

этот код протестирован и работает.

вы можете использовать как:

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

и это выход будет:

FIN  #FIN#
PUT  PUT

надеюсь, что это помогает.


вы можете рассмотреть возможность создания нового (другого имени, такого как convert) статического метода в классах перечисления.

public enum MyEnum{
      ....

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