(如何)可以在 Java 三元运算符语句中捕获异常?

(How) is it possible to catch an exception in a Java ternary operator statement?

我正在重新格式化一些我不完全理解的遗留代码,其中有几个变量分配有条件地将变量分配给两个格式化函数之一的输出,使用异常捕获如下:

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

这似乎是对异常处理的滥用,而且无论如何它都是大量重复的用于大量变量赋值的样板代码。如果不深入研究 foo 来确定可能导致异常的条件,我可以使用三元运算符表达式来简化它吗? IE。像这样:

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

但捕获了 foo(x) 可能抛出的异常。有没有办法在这个单行中做到这一点?或者,如果没有,是否有更好的单行表达式可以根据可能的异常在两个赋值之间进行选择?我正在使用 Java 8.

考虑这个案例

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

将此函数放入实用程序 class 中,然后将 myString = foo(x) 更改为 hee(x) 就足够了,因为您的原始对象 X 不是原始 java 类型。此解决方案向后兼容(因为这是遗留代码,我不确定您使用的是什么jdk)并且需要最少的解释。

毛巾答案已经很清楚了。只是想补充一点关于你的陈述:

it's a lot of repeated boilerplate code for a lot of variable assignments.

如果你不想重复赋值一个变量,你可以创建一个新方法给returnString值,如下所示:

String myString = assign(x);

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

用上述方法只需要给变量赋值一次

可以按如下方式使用惰性求值:

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 可能是可行的。

总之我没有看到干净的方法。