我有这段代码:
private void prepareContent() {
log.info("do something");
// success?
boolean suc = false;
suc = suc || uncompressToContent("file.tar.gz");
suc = suc || uncompressToContent("file.tgz");
for (int i = 0; i <= 9; i++) {
suc = suc || uncompressToContent("dir/" + i + ".tgz");
suc = suc || uncompressToContent("dir/" + i + ".tar.gz");
}
if (!suc) {
log.error("unable to do something");
}
}
Run Code Online (Sandbox Code Playgroud)
该函数对"file.tar.gz"和file.tgz"返回false.
问题是对uncompressToContent("dir/1.tgz")的调用返回true并且代码停止执行.其余代码未执行.
我不确定这是否是编译器中的错误.你怎么看?
补充:我忘了提到我需要执行对uncompressToContent的所有调用,并使用尽可能少的指令检查是否有任何返回true.
mik*_*era 10
编译器中没有错误.
只要suc设置为true(即从第一次uncompressToContent调用),则所有未来表达式将返回true 而不调用uncompressToContent.这是因为您使用的是短路布尔值或("||"),如果第一个参数为真,则不会评估第二个参数.
如果您想要进行所有呼叫,请使用普通或运算符("|")代替.
如果解压缩方法成功,则uncompress方法返回true,那么第一次发生这种情况时,suc将变为true.一旦suc成立,所有其他条件一旦suc被评估就会成立,因此OR的其他部分将不会被评估.因此,一旦至少一个成功,将不会尝试解压缩.
这称为短路并且是正确的行为,并且在大多数语言中是非常有用的属性.并且它也不是编译器优化,因为它是语言的已定义行为的一部分.
除了这个答案之外,我认为还有一些方法可以使这些代码更具可读性.首先,你确定你想要OR而不是AND吗?看起来你想要在一个文件没有正确压缩时立即退出,而不是因为正确解压缩而停止.
其次,更好的设计,恕我直言,将创建一个你要解压缩的所有文件名的列表,然后在该列表上执行for-each并执行所有的解压缩,这将使事情更具可读性.
第三,如果在大多数情况下解压缩成功,我认为异常处理比布尔返回值好得多.
这是我写这样的东西(我会把它分解成函数)
List<String> filenames = new ArrayList<String>();
this.collectFilenamesToDecompress(filenames) // Write one or more than one functions of this sort based on the semantics of your problem
try
{
for(String filename: filenames)
{
uncompressFile(filename); // This will throw an exception if there is a failure
}
} catch(Exception e)
{
// Announce that there was an error and you stopped decompressing because there was an error.
// Return or quit
}
// If you got here, everything is great!
Run Code Online (Sandbox Code Playgroud)