#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));
}