这是我的代码:
public enum Modification {
NONE, SET, REMOVE;
}
boolean foo(List<S> sList){
for (S s : sList) {
Modification modification = s.getModification();
switch (modification) {
case SET:
case REMOVE:
return true;
/*
case NONE:
break;
*/
}
}
return false;
}
当代码如上所示时,IntelliJ会说:
'for'语句不会循环少于...()报告任何for、while和do语句的示例,这些语句的主体保证最多执行一次。通常,这表明存在错误。
只有我做了以下更改,IntelliJ才会高兴:
for (S s : sList) {
Modification modification = s.getModification();
switch (modification) {
case SET:
case REMOVE:
return true;
case NONE:
break;
}
}
如果switch语句中不包含case NONE:,为什么for循环不循环?
5条答案
按热度按时间2cmtqfgy1#
我刚刚在eclipse中尝试了这个方法,结果在switch语句上出现了一个编译器警告。
枚举常量NONE在修改时需要在此枚举开关中有一个对应的case标签
为了解决警告,我有以下选项。
如果我添加了缺少的case语句,那么警告就不再出现了。这和添加缺少的case语句会让你的错误警告从intellij中消失是一样的。
如果没有case NONE的语句,你只能看到两个case,这两个case都返回true。如果不知道Modification的结构和NONE的额外值,看起来这个循环在第一次迭代时只会返回true。
当然,编译器应该知道Modification的值比SET和REMOVE的值多,所以警告只是为了好的风格。基本上你的代码可以工作,但这里有一些改进方法。
我会选择添加一个default语句而不是缺少的case。这将是更多的未来证明,以防以后更多的值被添加到枚举中。
就我个人而言,我并不喜欢在switch语句上使用fall through。你在使代码简洁方面所获得的好处是你在易读性上失去了IMHO。如果有人后来来并在SET和REMOVE之间添加了一个case,它可能会引入一个bug。此外,在一个方法的中途有一个return语句也会引起问题。如果有人想在return之前添加一些代码,他们可能会错过所有的地方。如果这个方法非常简单,那么多重返回就可以了,但是你已经说过这是一个简化的例子,所以如果这个代码块很复杂,我会避免使用它。
如果你能够使用Java 8,那么这看起来是新的流API的完美用例。
gxwragnw2#
我假设这是你仅有的三种情况,对吗?,所以基本上它说你要击中前两个中的一个并立即返回true,因此不循环,只需添加一个
default
情况,一切都应该正常工作,这也是很好的实践。基本上,它不能看到一个情况下,它不只是立即返回,而不迭代循环
ycggw6v23#
我会说这是一个假阳性。
第1个适应症:如果您通过调试器运行代码-并且列表中具有NONE修改的元素在具有其他修改的元素之前-它实际上将循环。
第二个适应症:当您查看生成的字节码时,它将switch语句转换为(某种程度上-它并不完全相同)
如果你把它放在你的代码中,IntelliJ不会抱怨。
第3种适应症:如果你在return之前加上一个额外的语句 *,警告就会消失,例如
System.out.println();
看来你用丢失的箱子标签欺骗了检查,可以简单地忽略警告。
j0pj023g4#
我认为IntelliJ的检查是错误的。我向JetBrains报告了
编辑:修好了
wz3gfoph5#
你的switch语句总是中断或返回。在第一种情况下,你什么都不做,也就是
falls through
。第二种情况下,return
s导致switch和循环停止。在第三种情况下,你break
switch语句导致循环停止。然而,它并没有停止for循环(也就是它一直在迭代)。要么为
SET
案例添加特定功能,要么更改您在REMOVE
和NONE
案例上的行为。如果没有
NONE
的情况下,switch不会循环,因为return
会中断循环并从函数返回一个值。break
会中断switch循环,但会继续for循环。根据OP的要求,提供额外的解释。
Falling through意味着下一个case将被执行,直到到达停止(
break
或return
)。这使得以下代码片段等价:等同于: