Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should you define a null/unknown value for Java enums?

Tags:

java

null

enums

When you define an enum for something that can be "undefined" in your interfaces, should you

  • define a separate enum value for that, or
  • just use enumValue = null for those situations?

For example,

serviceX.setPrice(Price priceEnum)

enum Price {  CHEAP, EXPENSIVE, VERRRY_EXPENSIVE, UNKNOWN } 

and priceEnum.UNKNOWN when needed

or

enum Price {  CHEAP, EXPENSIVE, VERRRY_EXPENSIVE } 

and priceEnum = null when needed?

Having a little debate on this. Some points that come to mind:

  • using Price.UNKNOWN saves some "if (price == null)" code. You can handle Price x's all values in a single switch-case
  • Depending on view technology, it may be easier to localize Price.UNKNOWN
  • using Price.UNKNOWN kind of causes "magic number" problem in the code, IMO. Here we have Price.UNKNOWN, elsewhere maybe Color.UNDEFINED, Height.NULLVALUE, etc
  • using priceValue = null is more uniform with how other data types are handled in Java. We have Integer i = null, DomainObject x = null, String s = null for unknown values as well, don't we?
  • Price.UNKNOWN forces you to decide whether null value is allowed univerally for all use cases. We may have method Price getPrice() which may return Price.UNKNOWN and setPrice(Price p) which is not allowed to accept Price.UNKNOWN. Since Price.UNKNOWN is always included in the enum's values, those interfaces look a little unclean. I know priceValue = null has the same problem (you cannot define in the interface whether null is accepted or not) but it feels a little cleaner and a little less misleading(?)
like image 592
user449236 Avatar asked Aug 22 '11 07:08

user449236


People also ask

Can enum have null values Java?

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.

Should enum be null?

An enum can be null. When an enum (like Color in this program) is a field of a class, it is by default set to null. It is not initialized to a value in the enum. It has no value.

Does enum accept null?

“c# enum value null” Code Answer An enum is a "value" type in C# (means the the enum is stored as whatever value it is, not as a reference to a place in memory where the value itself is stored). You can't set value types to null (since null is used for reference types only).

Is enum equals null safe?

equals() method. equals() method returns true if the specified object is equal to this enum constant. Using == operator. The == operator checks the type and makes a null-safe comparison of the same type of enum constants.


2 Answers

This is actually an example of applying Null Object pattern. IMHO it is always better to have a dummy object rather than null. For instance you can add dummy methods to null-object rather than scattering your code with null-checks all over the place. Very convenient.

Also the name of the enum gives you some additional semantics: is the price unknown, undefined, not trustworthy, not yet known? And what does it mean if the price is null?

UPDATE: As Aaron Digulla points out, Null Object pattern requires memory. But this isn't actually the case most of the time. In the traditional implementation you typically have a singleton for Null object used everywhere as there is no need for separate instances. It gets even better with enums because you get singleton semantics for free.

Another point is that null reference and reference to some object occupy the same amount of memory (say 4 bytes on 32-bit machine). It is the object being referenced that occupies some extra memory. But if this is a singleton, there is practically no memory overhead here.

like image 141
Tomasz Nurkiewicz Avatar answered Oct 09 '22 09:10

Tomasz Nurkiewicz


I'd say go with Price.UNKNOWN if that's a valid value for a price.

I agree with the drawbacks of dealing with null references that you mention, and I think they motivate the decision enough.

New languages, take Scala for example (and some older ones, Haskell) strain away from null references all together and uses option / maybe monads instead... for good reasons.

like image 36
aioobe Avatar answered Oct 09 '22 07:10

aioobe