[英]Why does Java allow null value to be assigned to an Enum?
这更像是一个设计问题,所以没有代码。 如果您希望我这样做,我可以发布创建 Enum 并将其分配给null
代码。 :))
我最近一直在思考这个问题,但想不出一个很好的理由。 Enum 常量是隐式的static和final 。 Enum 的意思是 - “我可以取一个存在于我中的常量的值”。 为什么允许 Enum 具有null
值? 为什么不将 Enum 的值隐式默认为Enum.DEFAULT
或Enum.None
? 这不是比允许 Enum 为null
更好的方法吗?
首先, null
表示实例不存在。 提供像DEFAULT
或NONE
这样的默认常量会改变这个含义。 其次,为什么你需要一些默认的东西来代表似乎不存在的东西? 这就是null
的目的。 基本上,您必须初始化并存储一个额外的对象,该对象甚至不应该存在。
顺便说一句,这不是语言选择。 如何实现枚举完全取决于您。 您可以在枚举中提供另一个常量,如DEFAULT
或UNKNOWN
,并避免将null
分配给代码中的引用。 这就是众所周知的空对象模式。 但是说null
赋值本身应该是编译器错误,那么我会说,因为无论如何Enum
被编译为Class
,所以使用null
来表示实例的不存在是完全有效的。
允许null
一个陷阱是在switch-case
使用enum
。 即使使用default
情况,以下代码也会抛出NPE
:
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:
或者,产生以下编译错误:
枚举 switch case 标签必须是枚举常量的非限定名称
Java 允许任何引用为空,并且对枚举的引用并没有那么特殊,以至于需要进行特殊情况来阻止它,或者提供已经明确指定和易于理解的另一个版本的行为。 Null 已经是一个完全足够的哨兵值:我们不需要另一个。
您的建议都没有说服力,因为它们都需要添加更多功能来支持它们。
无论如何,现在开始辩论这个问题已经晚了几年。
我认为, Enum.DEFAULT
意味着您的 enum 变量包含一个值,但null
不包含。 如果它为null
则可以将其解释为没有值,例如,您不能在其上调用非静态方法。
您可以向您的枚举添加行为(域驱动设计),例如添加一个名为 prettyPrint() 的公共方法,该方法根据您的枚举值返回一个字符串。 默认值/空值如何提供此自定义方法的实现?
如果您想用枚举表示 null,那么您必须通过手动使用带有 NONE 值的空对象模式和基于 NONE 值的 PrettyPrint() 自定义实现来明确这一点。
老了,我知道。 我是 Java 的一半。
为什么允许 Enum 具有空值?
我相信,用例很少。 例如,我们需要初始化一个 enum 变量来告诉我们它实际上不是 enum 的一部分,但是我们可以稍后更改它的值,使其成为它的一部分。 如果无法将枚举变量初始化为null
,那么我们将污染枚举定义。 因此,在我看来,诸如LibEnum.NONE
字段会LibEnum.NONE
库。 例如,您不希望将LibEnum.NONE
用作方法的参数,等等。
我发现它在我的词法扫描器中很有用,包括关键字和标点符号。 假设您有一个标识符"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
东西
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.