如何检测新值已添加到枚举中且未在 switch 中处理

问题描述 投票:0回答:4

有时我必须向项目中的枚举类型添加新值。

public enum Day {
  SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, 
   FILENOTFOUND //this one is new one
}

我想要的是对于我拥有的每个不处理新值的开关都有一个编译时错误,就像这个:

switch (color) {
        case MONDAY: 
        case TUESDAY: 
        case WEDNESDAY: 
        case THURSDAY: 
                    System.out.println("Mondays are bad.");
                     break;

        case FRIDAY: System.out.println("Fridays are better.");
                     break;

        case SATURDAY:
        case SUNDAY: System.out.println("Weekends are best.");
                     break;
    } 

有一个默认值:抛出一些异常还不够好,我希望它是编译时的。

我认为这是不可能的,但也许有人有一个巧妙的技巧......

我以为 Findbugs 会有一个规则来查找这些,但我只看到了这个: Eq:为枚举定义的协变 equals() 方法 (EQ_DONT_DEFINE_EQUALS_FOR_ENUM)

编辑:我选择马克的回复,我确实使用Eclipse,这听起来正是我所需要的!我根本不是 findbugs 方面的专家,所以我可能错过了这样的功能,尽管我不这么认为。

java enums compilation findbugs
4个回答
8
投票

Eclipse 有一个编译时警告/错误,您可以启用:“switch”上未涵盖枚举常量。

从项目属性(或常规首选项)中,转到 Java 编译器->错误/警告,选中启用项目特定设置。您会在潜在的编程问题下找到警告。默认情况下它设置为 Ignore,但您可以将其提高到 WarningError

编辑: 我认为这是不言而喻的,但我想我还是要说:这仅适用于您在 Eclipse 中进行开发或将其用于构建管理的情况。显然,Findbugs 或类似的等效工具将是“真正的”答案,因为它超越了 IDE,并且可以集成到构建过程中。


2
投票

您可以通过添加默认子句并在访问时进行记录来做到这一点:

switch (color) {
default:
    log.error("Unknown color in switch: " + color);
    break

case MONDAY: /*FALLTHROUGH*/
case TUESDAY: 

(添加失败注释可以帮助后来的维护人员确定您是否忘记了代码:-))

编辑从马克回答的评论中复制的澄清:

像这样的 IDE 功能信号案例对于开发人员在更改时来说很好,但它无法捕获代码所依赖的代码其他部分的更改。

它不会使包含枚举开关的古代代码对更改具有鲁棒性,除非针对新版本重新编译它们。

当客户端代码记录未处理的情况时,它确实有帮助;部署的代码并不总是能够完全控制其类路径或其上的库的版本。


0
投票

IntelliJ 是一项未设置所有情况的检查。它有一个自动修复功能来填补缺失的情况。


0
投票

自 Java 14(带有 JEP 361)以来,现在有 Switch Expressions 可以让您做到这一点。对于您的示例,这看起来像这样:

String feeling = switch (day) {
    case MONDAY => "Mondays are bad.";
    case TUESDAY => "Tuesdays are bad.";
    case WEDNESDAY => "Wednesdays are bad.";
    case THURSDAY => "Thursdays are bad.";
    case FRIDAY => "Fridays are better.";
    case SATURDAY => "Weekends are best.";
    case SUNDAY => "Weekends are best."
}
System.out.println(feeling);

如果添加新的枚举值

FILENOTFOUND
,则会出现编译错误:
java: the switch expression does not cover all possible input values

© www.soinside.com 2019 - 2024. All rights reserved.