SonarLint 的规则 java:S135 说:
循环不应包含多个“break”或“continue” 陈述 Break 和 continue 语句的使用增加了复杂性 控制流并使理解程序逻辑变得更加困难。 为了保持良好的程序结构,不应应用它们 每个循环不止一次。当有更多时,此规则会报告问题 比循环中的一个 Break 或 continue 语句更重要。代码应该是 如果有多个,则进行重构以提高可读性。
并给出了这个例子:
for (int i = 1; i <= 10; i++) { // Noncompliant; two "continue" statements
if (i % 2 == 0) {
continue;
}
if (i % 3 == 0) {
continue;
}
// ...
}
应重构为:
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0 || i % 3 == 0) {
continue;
}
// ...
}
但是看起来很奇怪。我有这个测试示例:
@Slf4j
public class TestService {
public int test(List<String> input) {
int count = 0;
for (String s : input) {
if ("ONE".equals(s)) {
log.info("one was called");
processOne(s);
continue;
}
String something = getSomethingBy(s);
if (something == null) {
log.info("something is null");
sendEmail();
continue;
}
if ("TWO".equals(s) && "hz".equals(something)) {
process(s);
count++;
}
}
return count;
}
和 sonarLint 声称:
如果我将此代码更改为:
public int testGoodForSonarLint(List<String> input) {
int count = 0;
for (String s : input) {
if ("ONE".equals(s)) {
log.info("one was called");
processOne(s);
} else {
String something = getSomethingBy(s);
if (something == null) {
log.info("something is null");
sendEmail();
} else if ("TWO".equals(s) && "hz".equals(something)) {
process(s);
count++;
}
}
}
return count;
}
看起来很糟糕。我讨厌那个 if-else 下巴和地狱般的 {}。该代码看起来像一棵圣诞树。 这是2个继续。在实际代码中,我有 4 个。因此,并不总是可以像 SonarLint 所建议的那样进行重构:
if (i % 2 == 0 || i % 3 == 0) {
continue;
}
因为我需要在每种情况下做一些事情,而不仅仅是继续。
也许我不明白一些东西,但通过继续或中断来交互循环看起来比括号地狱更好和可读。你觉得怎么样,是否可以重写这段代码?如果是,您将如何重构我的示例?
您可以为迭代创建另一种方法并在其中
return
。
那么,它就不会在方法内跳转,而只是停止方法的执行。
@Slf4j
public class TestService {
public int test(List<String> input) {
int count = 0;
for (String s : input) {
count = processString(s, input);
}
return count;
}
private int processString(String s, int count){
if ("ONE".equals(s)) {
log.info("one was called");
processOne(s);
return count;
}
String something = getSomethingBy(s);
if (something == null) {
log.info("something is null");
sendEmail();
return count;
}
if ("TWO".equals(s) && "hz".equals(something)) {
process(s);
count++;
}
return count;
}
}