Why does Java allow null value to be assigned to an Enum?
Firstly null
means non-existence of an instance. Providing a default constant like DEFAULT
or NONE
, will change that meaning. Secondly, why would you need something default to represent what seems to be non-existent? That is the purpose of null
. Basically, you would have to initialize and store an extra object, which shouldn't even exist whatsoever.
BTW, it's not a language choice. It's completely on you how you implement your enum. You can provide another constant like DEFAULT
, or UNKNOWN
in your enum, and avoid the assignment of null
to the reference in your code. This is famously known as Null Object Pattern. But saying that the null
assignment should itself be compiler error, then I would say, since an Enum
is anyways compiled to a Class
, so it would be perfectly valid to use null
to represent non-existence of an instance.
One pitfall of allowing null
though is with the usage of enum
in switch-case
. The below code will throw NPE
, even with a default
case:
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 does not allow a case null:
either, producing the following compile error:
an enum switch case label must be the unqualified name of an enumeration constant
Java allows any reference to be null, and references to enums aren't so special that a special case needs to be made to prevent it, or to provide another version of behaviour that is already well-specified and well-understood. Null is already a perfectly adequate sentinel value: we don't need another one.
Neither of your suggestions is convincing, as they would both require addition of yet further features to support them.
In any case it is several years too late to start debating the point.
I think, Enum.DEFAULT
means that your enum variable contains a value, but null
doesn't. If it's null
it can be interpreted that it has no value, you can't invoke non-static methods on it for example.