IntelliJ 抱怨“for statement not loop”?

2022-09-03 15:01:57

这是我的代码:

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 循环不循环?


答案 1

我刚刚在eclipse中尝试了一下,你最终在switch语句上得到了一个编译器警告。

枚举常量 NONE 需要在此枚举开关中具有相应的大小写标签

要解决该警告,我提供了以下选项。

  • 添加默认大小写
  • 添加缺少的案例语句
  • 将@SuppressWarnings“不完整开关”添加到 foo()

如果我添加缺少的案例语句,则警告不再出现。与添加缺少的大小写相同,使您的错误警告从 intellij 中消失。

如果没有 case NONE 的语句,您只能看到两个案例,这两个案例都返回 true。在不知道 Modification 的结构和 NONE 的额外值的情况下,看起来这个循环在循环的第一次迭代时只返回 true。

当然,编译器实际上应该知道修改的值比 SET 和 REMOVE 更多,因此警告只是为了好的样式。基本上,您的代码可以正常工作,但以下是改进它的方法。

我会选择添加一个默认语句,而不是缺少大小写。如果以后将更多值添加到枚举中,这将是更未来的证明。例如

switch (modification) 
{
  case SET:
  case REMOVE:
    return true;
  default:
    break;
}

就个人而言,我不喜欢使用掉线开关语句。恕我直言,您在使代码简洁方面获得的收益在易读性方面却失去了。如果有人后来来在SET和REMOVE之间添加一个案例,它可能会引入一个错误。此外,在方法中途使用 return 语句也会导致问题。如果有人想在返回之前添加一些代码,他们可能会错过所有的地方。如果方法非常简单,那么多次返回是可以的,但你已经说过这是一个简化的例子,所以如果这个代码块很复杂,我会避免它。

如果您能够使用Java 8,那么这看起来是新流API的完美用例。像下面这样的东西应该可以工作。

return sList.stream().anyMatch(
  modification -> (modification==Modification.SET || modification==Modification.REMOVE)
);

答案 2

我假设这些是你唯一的三个案例,所以基本上它说你会击中前两个中的一个并立即返回true,因此不循环,只是添加一个案例,一切都应该工作正常,这也是很好的做法。default

基本上,它看不到一个案例,即它不会在没有迭代循环的情况下立即返回