【问题标题】:Is there a way to enforce that you're switching over all defined values of an enum in Java? [duplicate]有没有办法强制您在 Java 中切换枚举的所有定义值? [复制]
【发布时间】:2017-09-10 18:27:09
【问题描述】:

假设你有一个包含 3 个值的枚举:

enum Colors { RED, GREEN, BLUE }

您以某种方法切换它的所有值,认为您已经处理了所有情况:

switch (colors) {
    case RED: ...
    case GREEN: ...
    case BLUE: ...
}

然后,您向枚举添加一个新值:

enum Colors { RED, GREEN, BLUE, YELLOW }

一切仍然编译得很好,除了你在方法中默默地错过了YELLOW 的情况。有没有办法在这种情况下引发编译时错误?


编辑:不明白为什么这被标记为Can I add and remove elements of enumeration at runtime in Java 的欺骗。由于答案是“否”,这意味着应该可以在编译时知道枚举的所有值,因此我所要求的应该是编译器/一些代码分析工具可以实现的,对吧?

【问题讨论】:

  • default: throw new UnsupportedOperationException();?
  • @Colonder 绝对不是那个问题的重复。
  • @Colonder 取消将此标记为骗子,好吗? :)

标签: java enums switch-statement


【解决方案1】:

没有。但是枚举是类。所以你可以使用多态性:

enum Color { 
    RED {
        @Override
        public void foo() { ... }
    },
    GREEN {
        @Override
        public void foo() { ... }
    },
    BLUE {
        @Override
        public void foo() { ... }
    };

    public abstract void foo();
}

现在,如果您添加颜色,编译器将不允许您添加它,因为它不会覆盖抽象方法。

而不是

switch (color) {
    case RED: ...
    case GREEN: ...
    case BLUE: ...
}

你可以使用

color.foo();

请注意,如果 Kotlin 是一个选项,Kotlin 允许做你想做的事。

另请注意,蓝色是一种颜色,而不是一种颜色。所以枚举应该命名为 Color,而不是 Colors。

【讨论】:

  • 为这里提到 Kotlin 点赞!
  • 没错,用多态替换条件是解决这个问题的OOP方式。
  • 这是一个非常非常有趣的答案。不过,我不确定是否要将逻辑放入我的Colors 枚举中,哈哈 :) 这实际上是将枚举变成了一个接口。
  • 您可以使用访问者模式来使用多态性,同时仍将逻辑排除在枚举之外。但是如果你不能修改枚举,除了在运行时出现异常、单元测试或使用编译器进行检查的语言之外,你无能为力。
【解决方案2】:

这取决于编译器。 Eclipse IDE 内置编译器可以配置为在这种情况下引发错误。

Windows/Preferences Java Compiler Errors/Warnings “Incomplete 'switch' case on enum”可以设置为“Error”。

编辑:

甚至还有一个子选项“即使存在‘默认’情况也发出信号”。

【讨论】:

  • 有趣。我不知道 Eclipse 有这个功能。如果开关有默认情况(会抛出运行时异常)会发生什么?在这种情况下它是否被认为是完整的(抱歉,这里没有 eclipse 可以快速测试)?
  • @JB 刚刚将信息添加到我的答案中
  • 谢谢@Ralf
【解决方案3】:

我不认为有这样做的默认方式。使用一些外部工具或许可以实现。

为什么不在 switch 语句中提供默认值并引发异常。此外,你应该有足够的单元测试来测试这个场景,如果你编译你的项目并且你所有的单元测试都是好的,这意味着你的测试不够深入。

【讨论】:

  • 这可能是真正应该留给编译器的很多工作。 (当然,在 Java 中你不能,这是一种耻辱。)你关于使用测试进行此类检查的推理可以在更广泛的意义上应用;那么为什么我们有类型和东西以及任何编译时检查呢?
猜你喜欢
  • 2013-05-31
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 2019-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多