【问题标题】:Can you create a not-defined enum value in Java, like in .NET?你能在 Java 中创建一个未定义的枚举值吗,就像在 .NET 中一样?
【发布时间】:2017-09-10 18:14:09
【问题描述】:

与 .NET 相比,我在 Java 方面没有太多经验。在 .NET 中,枚举被视为整数的瘦包装器,因此您可以轻松创建未命名的枚举值。例如:

// C# code
public enum Colors { Red, Green, Blue }

Console.Writeline(Colors.Red + " " + Colors.Green + " " + Colors.Blue); // Red Green Blue

var unknown = (Colors)(-1);
Console.WriteLine(unknown); // -1

在 Java 中可以做同样的事情吗?

编辑:这似乎是因为这段代码无法编译:

// Java code
enum Colors { R, G, B }

static int f(Colors c) {
    switch (c) {
        case R: return 1;
        case G: return 2;
        case B: return 3;
    } // Compiler complains about a missing return statement
}

【问题讨论】:

  • 我当然希望不会!这听起来是个糟糕的主意!
  • @JoeC 我也同意。我有点迂腐,所以在我的 .NET 代码中,我总是遇到 default: 的情况,每次打开枚举时我都会抛出异常,即使我已经处理了所有定义的值。我想知道我是否必须为 Java 做同样的事情。
  • 绝对不是。在 Java 中,枚举是类型安全的,你根本无法表达这个概念。
  • 编辑中的代码无法编译,因为编译器防御性地假设在创建使用枚举的编译类文件后可能会更改(扩展)Colors 枚举。因此,如果 Colors 枚举在两者之间发生变化,那么(在编译时)完整的案例列表可能会在稍后运行时变得不完整。
  • @RalfKleberhoff 我明白了。但是,如果 enum 和 switch 语句位于同一个 jar 中,编译器是否能够处理它?

标签: java c# enums


【解决方案1】:

Java 实现 enums 与 C# 不同:不是让它们成为 ints 的瘦包装器,而是使它们成为对象周围的瘦包装器,compiler-aided improvement on the type-safe enum pattern

编译器确保不可能创建不包含在类型中的enum 的实例。

每种方法都有优点和缺点。 C# 更接近于 C 和 C++ enums,它们的行为类似于命名数字常量的集合。这使得创建[Flag] 枚举成为可能——这是Java enums 无法实现的。

另一方面,Java enums 是完全可以工作的对象,具有自己的方法,并具有实现接口的能力。方法可以作为扩展添加到 C#enums,但不能实现接口。

【讨论】:

  • 感谢您的回答,内容非常丰富(我赞成)。你知道为什么我在编辑中发布的代码无法编译吗?
  • 您需要添加大小写默认值,如:'default: throw new IllegalArgumentException();'
  • @JamesKo 我认为这是编译器的一个缺点。您可以传递给f() 的唯一其他值是null,但如果您这样做了,switch 语句就会崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
  • 2015-11-28
  • 1970-01-01
相关资源
最近更新 更多