java IntelliJ 抱怨“for 语句不循环”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36304002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IntelliJ complaining "for statement does not loop"?
提问by Koray Tugay
This is the code I have:
这是我的代码:
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;
}
And when the code is as seen above, IntelliJ will say:
当代码如上所示时,IntelliJ 会说:
'for' statement does not loop less... () Reports any instance of for, while and do statements whose bodies are guaranteed to execute at most once. Normally, this is an indication of a bug.
'for' 语句不会循环更少... () 报告 for、while 和 do 语句的任何实例,其主体保证最多执行一次。通常,这表明存在错误。
Only if I make the following change, IntelliJ will be happy:
只有我做出以下改变,IntelliJ 才会开心:
for (S s : sList) {
final Modification modification = s.getModification();
switch (modification) {
case SET:
case REMOVE:
return true;
case NONE:
break;
}
}
Why is my for loop not looping if case NONE:is not included in the switch statement?
如果case NONE:未包含在 switch 语句中,为什么我的 for 循环不循环?
采纳答案by Ben Thurley
I just tried this in eclipse and you end up with a compiler warning on the switch statement.
我刚刚在 eclipse 中尝试过这个,你最终在 switch 语句上得到一个编译器警告。
The enum constant NONE needs a corresponding case label in this enum switch on Modification
枚举常量 NONE 需要在此枚举中对应的 case 标签打开修改
To resolve the warning I'm given the following options.
为了解决警告,我提供了以下选项。
- Add default case
- Add missing case statements
- Add @SuppressWarnings 'incomplete-switch' to foo()
- 添加默认情况
- 添加缺少的 case 语句
- 将 @SuppressWarnings 'incomplete-switch' 添加到 foo()
If I add the missing case statement then the warning no longer appears. The same as adding the missing case makes your errorwarning disappear from intellij.
如果我添加缺少的 case 语句,则不再出现警告。与添加缺失大小写相同,您的错误警告会从 intellij 中消失。
Without the statement for case NONE you can only see two cases, both of which return true. Without knowing the structure of Modification and the extra value of NONE it looks like this loop would just return true on the first iteration of the loop.
如果没有 case NONE 的语句,您只能看到两种情况,这两种情况都返回 true。在不知道 Modification 的结构和 NONE 的额外值的情况下,这个循环看起来只会在循环的第一次迭代中返回 true。
Of course the compiler should actually know that there are more values for Modification than SET and REMOVE so the warning is just for good style. Basically your code works but here's how to improve it.
当然,编译器实际上应该知道 Modification 的值比 SET 和 REMOVE 多,所以警告只是为了好的风格。基本上你的代码可以工作,但这里是如何改进它。
I would choose to add a default statement rather than the missing case. This would be more future proof in case more values are later added to the enum. E.G.
我会选择添加默认语句而不是缺少的情况。如果以后将更多值添加到枚举中,这将更具未来证明。例如
switch (modification)
{
case SET:
case REMOVE:
return true;
default:
break;
}
Personally I'm not a fan of using the fall through on switch statements. What you gain in making the code concise you lose in legibility IMHO. If someone later comes and adds a case between SET and REMOVE it could introduce a bug. Also, having a return statement mid-way through a method can also cause problems. If someone wants to add some code just before the return they may miss all the places. If the method is very simple then multiple returns is fine but you've stated that this is a simplified example and so if this block of code is complicated I would avoid it.
就个人而言,我不喜欢在 switch 语句中使用 fall through。恕我直言,您在使代码简洁时失去了易读性所获得的收益。如果后来有人来在 SET 和 REMOVE 之间添加一个案例,它可能会引入一个错误。此外,在方法中途使用 return 语句也会导致问题。如果有人想在返回之前添加一些代码,他们可能会错过所有地方。如果该方法非常简单,那么多次返回就可以了,但是您已经声明这是一个简化的示例,因此如果此代码块很复杂,我会避免使用它。
If you're able to use Java 8 then this looks to be the perfect use case for the new stream API. Something like the following should work.
如果您能够使用 Java 8,那么这看起来是新流 API 的完美用例。像下面这样的东西应该可以工作。
return sList.stream().anyMatch(
modification -> (modification==Modification.SET || modification==Modification.REMOVE)
);
回答by Gerald Mücke
I'd say its a false positive.
我会说这是一个误报。
1st indication: If you run your code through a debugger - and have elements with NONE modification in the list before an element with other modifications - it will actually loop.
第一个迹象:如果您通过调试器运行您的代码 - 并且在具有其他修改的元素之前在列表中具有 NONE 修改的元素 - 它实际上会循环。
2nd indication: When you look at the generated bytecode, it transforms the switch statement to (sort of - its not exactlythe same)
第二个迹象:当您查看生成的字节码时,它将 switch 语句转换为(有点 - 它不完全相同)
for (S s : sList) {
Modification modification = s.getModification();
switch (modification.ordinal()) {
case 1:
case 2:
return true;
}
}
If you put that in your code, IntelliJ does not complain.
如果你把它放在你的代码中,IntelliJ 不会抱怨。
3rd indication:
the warning dissappears if you put an additional statement beforethe return, i.e. System.out.println();
第三个迹象:如果您在返回之前添加附加语句,则警告消失,即System.out.println();
switch (modification) {
case SET:
case REMOVE:
System.out.println()
return true;
Seems you tricked the inspection with the missing case label and could simply ignore the warning.
似乎您用缺少的案例标签欺骗了检查,并且可以简单地忽略警告。
回答by AngryDuck
i assume these are your only three cases right?, so basically its saying you are going to hit one of the first two and instantly return true, therefore not looping, just add a default
case and everything should work ok, this is good practice also btw.
我认为这是您仅有的三个案例,对吗?,所以基本上它说您将点击前两个中的一个并立即返回 true,因此不循环,只需添加一个default
案例,一切都应该正常,顺便说一句,这也是一个好习惯.
basically it cant see a case where it doesnt just return instantly without iterating the loop
基本上它看不到这样一种情况,即它不会在不迭代循环的情况下立即返回
回答by bwt
回答by Lars de Bruijn
Your switch case always breaks or returns. In the first case, you do nothing aka it falls through
. The second case return
s which causes both the switch and the loop to stop. In the third case you break
the switch statement which causes it to stop. It does not however stop the for loop (aka, it keeps iterating).
您的开关盒总是损坏或返回。在第一种情况下,你什么都不做,也就是它falls through
。第二种情况return
s 导致开关和循环都停止。在第三种情况下,你break
的 switch 语句会导致它停止。然而,它不会停止 for 循环(也就是,它不断迭代)。
Either add specific functionality for the SET
case or change your behaviour on the REMOVE
and NONE
cases.
为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;
}
Your switch is not looping without the NONE
case because return
breaks the loop and returns a value from the function. break
breaks the switch loop but continues the for loop.
您的 switch 在没有NONE
大小写的情况下不会循环,因为return
会中断循环并从函数返回一个值。break
中断 switch 循环但继续 for 循环。
By request of OP an extra explanation.
应 OP 的要求提供额外的解释。
Falling through means the next case will be executed until a stop (break
or return
) is reached. This makes the following code snippets equivelant:
Falling through 表示将执行下一个案例,直到到达停止(break
或return
)。这使得以下代码片段等效:
case SET:
case REMOVE:
return true;
is the same as:
是相同的:
case SET:
return true;
case REMOVE:
return true;