Проверка значения перечисления на нуль и обработка исключений

#java #enums

Вопрос:

Я пытаюсь оптимизировать приведенный ниже фрагмент кода, я хотел посмотреть, есть ли способ избежать двойного исключения и оптимизировать его так, чтобы оно создавалось только один раз. есть какие-нибудь рекомендации?

Пользователь-это перечисление, и если значение не найдено, метод valueOf вызовет исключение IllegalArgumentException, в то время как я также должен выполнить здесь проверку на значение null и, следовательно, еще одну проверку на пустоту.

 private UserContext getContext(String name) {

        UserContext context = null;

        if (StringUtils.isBlank(name)) {
            throw new IllegalArgumentException("name cannot be Null or empty");
        }

        try {
        context  = map.get(User.valueOf(name.toUpperCase()));

        }catch(IllegalArgumentException e) {
            throw new IllegalArgumentException("name is not in the list of given names"  name);
        }

        return context;

    }
 

Комментарии:

1. почему пять баллов ?

2. Я предполагаю, что вы могли бы установить какой-то флаг вместо того, чтобы выдавать броски в этих двух местах, а затем бросать из одного места в конце функции, если этот флаг был установлен. Я думаю, что это было бы хуже во всех отношениях по сравнению с вашим текущим кодом (сложнее следовать логике, менее идиоматично, вероятно, более подвержено ошибкам). (Кроме того, код не будет «бросать дважды», если вы окажетесь в первом теле if, код прервется и не достигнет второго.) Провалиться так рано, как это, как правило, хорошая идея. Бонус: Ваш код потенциально уязвим для «Отраженных атак XSS», можете ли вы обнаружить эту ошибку и исправить ее?

Ответ №1:

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

Кроме того, проверка на null/empty кажется избыточной и может быть полностью удалена.

 public enum User {
    // ... existing code

    public static User byName(String name) {
        // this check may be removed completely
        if (StringUtils.isBlank(name)) {
            throw new IllegalArgumentException("name cannot be null or empty");
        }

        return Arrays.stream(User.values())
            .filter(v -> v.name().equalsIgnoreCase(name)) // null-safe case insensitive check
            .findFirst() // Optional<User>
            .orElseThrow(() -> new IllegalArgumentException("name is not in the list of given names: "   name));
    }
}
 

Затем метод getContext может быть переработан, чтобы быть таким же простым, как:

 private UserContext getContext(String name) {
    return map.get(User.byName(name));
}