我正在重新格式化一些我不完全理解的遗留代码,其中有几个变量分配,它们使用异常捕获有条件地将变量分配给两个格式化函数之一的输出:
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。
答案 0 :(得分:4)
可以使用如下的惰性评估:
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
进行更复杂的重新设计可能是可行的。
简而言之,我看不到干净的方法。
答案 1 :(得分:2)
洗碗布的答案已经很清楚了。只是想添加一些关于您的声明:
有很多重复的样板代码,用于很多变量分配。
如果不想重复分配变量,则可以创建一个新方法以返回String
值,如下所示:
String myString = assign(x);
String assign(String x) {
try {
return foo(x);
} catch (Exception e) {
return bar(x);
}
}
您只需使用上述方法分配一次变量即可。
答案 2 :(得分:1)
考虑这种情况
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),并且需要的解释很少。