Как переопределить значение перечисления - PullRequest
14 голосов
/ 05 октября 2011

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

Я пытаюсь основной

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

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

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

Ответы [ 5 ]

18 голосов
/ 05 октября 2011

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

public static MyEnum permissiveValueOf(String name) {
    for (MyEnum e : values()) {
        if (e.name().equals(name)) {
            return e;
        }
    }
    return null;
}
9 голосов
/ 05 октября 2011

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

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

Цитата из Javadoc для EnumUtils.getEnum :

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

Этот метод отличается от Enum.valueOf (java.lang.Class, java.lang.String) тем, что не выдает исключение для неверное имя перечисления.

2 голосов
/ 06 декабря 2012

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

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

Надеюсь, это поможет.

2 голосов
/ 05 октября 2011

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

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

    return null;
}
0 голосов
/ 05 октября 2011

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

public enum MyEnum{
      ....

     public static MyEnum convert(Object value){
       ...
     }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...