(Как) возможно ли поймать исключение в операторе троичного оператора Java? - PullRequest
2 голосов
/ 12 июня 2019

Я переформатирую некоторый унаследованный код, который я до конца не понимаю, и в нем есть несколько переменных, которые условно присваивают переменные выводу одной из двух функций форматирования, используя перехват исключений, например так:

String myString;
try {
    myString= foo(x);
} catch (Exception e) {
    myString= bar(x);
}

Это похоже на злоупотребление обработкой исключений, и в любом случае это много повторяющихся шаблонных кодов для множества назначений переменных. Не углубляясь в foo, чтобы определить условия, которые могут вызвать исключения, могу ли я упростить это с помощью выражения троичного оператора? То есть как то так:

String myString = foo(x) ? foo(x) : bar(x)

но перехватывает исключение, которое может быть выдано foo(x). Есть ли способ сделать это в этом однострочном? Или, если нет, есть ли лучшее однострочное выражение, которое выбирает между двумя присваиваниями на основе возможного исключения? Я использую Java 8.

Ответы [ 3 ]

4 голосов
/ 12 июня 2019

Можно использовать ленивую оценку следующим образом:

String myString = attempt(() -> foo(x), () -> bar(x));

public static <T> T attempt(Supplier<T> a, Supplier<T> b) {
    try {
        return a.get();
    } catch (Exception e) {
        return b.get();
    } 
}

Это нехорошо и просто было бы одним этапом всего рефакторинга.

Один шаблон для таких конструкций, которые вы видели, был бы сообщением о результате процесса, который, возможно, генерирует IOException.

Уродливым шаблоном может быть исключение NullPointerException или тому подобное, когда данные являются необязательными. затем возможно более сложное изменение с Optional.ofNullable и .map на другой Optional.

Короче не вижу чистого пути.

2 голосов
/ 12 июня 2019

Ответ мочалки уже ясен. Просто хочу добавить немного о вашем утверждении:

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

Если вы не хотите назначать переменную повторно, вы можете создать новый метод для возврата значения String, как показано ниже:

String myString = assign(x);

String assign(String x) {
    try {
        return foo(x);
    } catch (Exception e) {
        return bar(x);
    }
}

Вам необходимо присвоить переменную только один раз с помощью вышеуказанного метода.

1 голос
/ 12 июня 2019

С учетом этого случая

String myString;
try {
    myString= foo(x);
} catch (Exception e) {
    myString= bar(x);
}

Что произойдет, если foo(x) сгенерирует исключение, поскольку он не может обрабатывать строки с символами UTF-16, тогда вместо этого мы будем использовать bar(x).

В вашем случае с троичным оператором String myString = foo(x) ? foo(x) : bar(x), если вы сначала проверите foo(x), и он выдаст ошибку, то вся ваша программа выдаст ошибку, что приведет нас обратно к установке оператора try вокруг вашего троичного оператора.

Без оригинального кода трудно сказать, почему разработчики сделали это таким образом, но выше приведен пример того, почему они выбрали эту практику проектирования.Также хорошо отметить, что в данном случае не весь устаревший код плох;Устаревший код работает, удобен в обслуживании и легко читается для новых разработчиков.Поэтому, как говорится в комментарии, лучше оставить все так.

Редактировать

Вы сказали, что хотели какой-то 1 вкладыш, который уменьшает котельную плиту.Вы можете сделать что-то вроде этого

void hee(String mystring) {
    try {
        myString= foo(x);
     } catch (Exception e) {
        myString= bar(x);
     }
}

Поместить эту функцию в служебный класс с последующим изменением myString = foo(x) на hee(x) будет достаточно, поскольку ваш исходный объект X не является примитивным типом Java.Это решение обратно совместимо (так как это устаревший код, я не уверен, какой jdk вы используете) и требует минимального объяснения.

...