Как переопределить значение для перечисления

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

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

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

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

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

Ответы

Ответ 1

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

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

Ответ 2

Использование Apache Commons Lang:

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

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

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

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

Ответ 3

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

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

    return null;
}

Ответ 4

Вам не нужно переопределять 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

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

Ответ 5

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

public enum MyEnum{
      ....

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