这是我的代码:
public enum Modification {
NONE, SET, REMOVE;
}
boolean foo(){
for (S s : sList) {
final 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) {
final Modification modification = s.getModification();
switch (modification) {
case SET:
case REMOVE:
return true;
case NONE:
break;
}
}
如果 case NONE:未包含在switch语句中,为什么我的for循环不循环?
答案 0 :(得分:7)
我刚刚在eclipse中试过这个,你最终会在switch语句中发出编译器警告。
枚举常量NONE在修改
上的枚举开关中需要相应的案例标签
要解决警告,我会给出以下选项。
如果我添加了缺失的case语句,则警告不再出现。与添加缺失的案例相同,使您的错误警告从intellij消失。
如果没有case NONE的语句,你只能看到两种情况,两种情况都返回true。在不知道修改的结构和NONE的额外值的情况下,看起来这个循环只会在循环的第一次迭代时返回true。
当然编译器应该知道修改的值多于SET和REMOVE,所以警告只是为了好的风格。基本上你的代码可以工作,但是这里是如何改进它。
我会选择添加默认语句而不是丢失的案例。如果稍后将更多值添加到枚举中,这将是更具前瞻性的证据。 E.G。
switch (modification)
{
case SET:
case REMOVE:
return true;
default:
break;
}
就我个人而言,我不喜欢在switch语句中使用fall-through。你在使代码简洁的过程中获得了什么,你在可读性方面失去了恕我直言。如果有人后来在SET和REMOVE之间添加一个案例,它可能会引入一个错误。此外,通过方法中途返回语句也可能导致问题。如果有人想在返回之前添加一些代码,他们可能会错过所有的地方。如果方法非常简单,那么多次返回就没问题,但你已经说过这是一个简化的例子,所以如果这段代码很复杂,我会避免它。
如果您能够使用Java 8,那么这看起来是新流API的完美用例。以下内容应该有效。
return sList.stream().anyMatch(
modification -> (modification==Modification.SET || modification==Modification.REMOVE)
);
答案 1 :(得分:2)
我认为这是你唯一的三种情况吗?所以基本上它说你要打前两个中的一个然后立即返回true,因此不循环,只需添加一个default
案例,一切都应该有效好的,这也是很好的做法。
基本上它无法看到它不会立即返回而不迭代循环的情况
答案 2 :(得分:2)
我说它是误报。
第一个迹象: 如果您通过调试器运行代码 - 并且在具有其他修改的元素之前在列表中包含NONE修改的元素 - 它将实际循环。第二个指示: 当你查看生成的字节码时,它会将switch语句转换为(排序 - 它不是完全相同)
for (S s : sList) {
Modification modification = s.getModification();
switch (modification.ordinal()) {
case 1:
case 2:
return true;
}
}
如果你把它放在你的代码中,IntelliJ不会抱怨。
第3个指示:
如果您在返回之前添加了一个附加声明,即System.out.println();
switch (modification) {
case SET:
case REMOVE:
System.out.println()
return true;
似乎你用缺少的案例标签欺骗了检查,并且可以简单地忽略警告。
答案 3 :(得分:1)
我认为IntelliJ的检查是错误的。我向JetBrains
报告了这个问题编辑:已修复
答案 4 :(得分:0)
您的开关盒总是断裂或返回。在第一种情况下,你什么也不做,falls through
。第二种情况return
导致开关和循环停止。在第三种情况下,你break
导致它停止的switch语句。然而,它不会停止for循环(也就是说,它会继续迭代)。
为SET
案例添加特定功能,或在REMOVE
和NONE
案例中更改您的行为。
public enum Modification {
NONE, SET, REMOVE;
}
boolean foo(){
for (S s : sList) {
final Modification modification = s.getModification();
switch (modification) {
case SET:
// This case falls through to the REMOVE case
case REMOVE:
return true; // This statement stops the switch, loop and returns true
case NONE:
break; // This statement stops the switch and continues the loop.
}
}
return false;
}
如果没有NONE
情况,您的交换机不会循环,因为return
会中断循环并从函数返回一个值。 break
打破了切换循环,但继续for循环。
根据OP的要求提供额外的解释。
下降意味着下一个案例将被执行,直到达到停止(break
或return
)。这使得以下代码片段等效:
case SET:
case REMOVE:
return true;
与:
相同case SET:
return true;
case REMOVE:
return true;