IntelliJ抱怨"for语句不循环"?

Kor*_*gay 12 java for-loop intellij-idea

这是我的代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

当代码如上所示时,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;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果case NONE: 不包含在switch语句中,为什么我的for循环不循环?

Ben*_*ley 8

我刚刚在eclipse中尝试了这个,你最终在switch语句中发出了编译器警告.

枚举常量NONE在修改时的枚举开关中需要相应的case标签

为了解决警告,我给出了以下选项.

  • 添加默认案例
  • 添加缺少的案例陈述
  • 将@SuppressWarnings'incomplete-switch'添加到foo()

如果我添加了缺少的case语句,则不再显示警告.与添加缺失的案例相同,使您的错误警告从intellij中消失.

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

当然,编译器实际上应该知道修改的值多于SET和REMOVE,因此警告只是为了良好的风格.基本上你的代码工作,但这里是如何改进它.

我会选择添加默认语句而不是丢失的案例.如果稍后将更多值添加到枚举中,这将是更具前瞻性的证据.例如

switch (modification) 
{
  case SET:
  case REMOVE:
    return true;
  default:
    break;
}
Run Code Online (Sandbox Code Playgroud)

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

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

return sList.stream().anyMatch(
  modification -> (modification==Modification.SET || modification==Modification.REMOVE)
);
Run Code Online (Sandbox Code Playgroud)