这更像是一个设计问题,所以没有代码。我可以创建一个枚举和分配到 null如果你想让我这样做的代码。:))
null
我最近想了很多,但是想不出一个好理由。Enum 常量隐式为 静电干扰和 期末考试。Enum 的意思是说——“我可以取出存在于我体内的一个常量的值”。为什么允许 Enum 具有 null值?为什么不将 Enum 的值隐式默认为 Enum.DEFAULT或 Enum.None?这难道不是一种比允许 Enum 为 null更好的方法吗?
Enum.DEFAULT
Enum.None
我认为,Enum.DEFAULT意味着您的枚举变量包含一个值,但是 null不包含。如果它是 null,它可以被解释为它没有值,例如,您不能调用它上面的非静态方法。
首先,null表示实例不存在。提供像 DEFAULT或 NONE这样的默认常量将改变这种意义。其次,为什么需要默认值来表示似乎不存在的东西?这就是 null的目的。基本上,您必须初始化并存储一个额外的对象,这个对象根本就不应该存在。
DEFAULT
NONE
顺便说一句,这不是语言选择。如何实现枚举完全取决于您自己。您可以在枚举中提供另一个常量,如 DEFAULT或 UNKNOWN,并避免将 null赋值给代码中的引用。这就是众所周知的 空对象模式。但是,如果说 null赋值本身应该是编译器错误,那么我会说,因为 Enum无论如何都是编译成 Class的,所以使用 null表示实例不存在是完全有效的。
UNKNOWN
Enum
Class
但是允许 null的一个缺陷是在 switch-case中使用 enum。下面的代码将抛出 NPE,即使在 default的情况下:
switch-case
enum
NPE
default
public class Demo { enum Color { WHITE, BLACK; } public static void main(String[] args) { Color color = null; switch (color) { // NPE here case WHITE: break; case BLACK: break; default: break; // null value does not fall into the default } } }
Java 也不允许使用 case null:,产生以下编译错误:
case null:
枚举开关大小写标签必须是枚举常数的非限定名
您可以将行为添加到您的枚举(域驱动设计) ,例如,添加一个名为 pretyPrint ()的公共方法,该方法根据您的枚举值返回一个 String。缺省/空值如何提供这个自定义方法的实现?
如果你想用枚举表示 null,那么你必须手动使用一个带有 nONE 值的空对象模式,以及一个基于 nONE 值的 pretyPrint ()的自定义实现。
Java 允许任何引用为 null,并且对枚举的引用并不特殊,因此不需要特殊的情况来防止它,或者提供另一个已经指定和理解的行为版本。Null 已经是一个完全足够的哨兵值: 我们不需要另一个。
Neither of your suggestions is convincing, as they would both require addition of yet further features to support them.
无论如何,现在开始讨论这个问题已经晚了好几年。
老了,我知道,我有一半爪哇血统。
为什么允许 Enum 具有空值?
我相信,用例很少。例如,我们需要初始化一个枚举变量来告诉我们它不是枚举的一部分,但是我们可以稍后更改它的值,以便它成为它的一部分。如果没有办法将枚举变量初始化为 null,那么我们将污染枚举定义。因此,在我看来,像 LibEnum.NONE这样的字段会扰乱库。例如,您不希望在其他方法之间使用 LibEnum.NONE作为方法的参数。
LibEnum.NONE
我发现它在我的词汇扫描仪中很有用,包括关键词和标点符号。假设您有一个标识符 "blah"。然后检查它是否是任何关键字。
"blah"
private Keywordv getKeywordValue(String id) { switch (id.length()) { case 2: { switch (id) { case "do": return Keywordv.DO; case "if": return Keywordv.IF; case "is": return Keywordv.IS; // ... } break; } // ... } return null; }
多亏了 null,这样就很容易验证标识符是否是关键字。
id == null
否则我们必须定义类似于 Keywordv.__NULL的东西
Keywordv.__NULL