I'm designing a class that holds several types of data. Some of the properties are optional. For example, let's say I have a class that represents a person, and one of the properties is occupation. I have another property, military rank, but this property is can only be retrieved if the person's occupation is military. What's the best way to handle this?
- Have
getMilitaryRank()
throwIllegalStateException
if the occupation isn't military - Have
getMilitaryRank()
return anOptional<Rank>
- Return null if the occupation is invalid (I don't like nulls)
- Something else?
Idea 1 works because the user can check the occupation prior to calling this method, making sure they don't call it on an invalid person.
Idea 2 seems unnecessary, because you can infer whether the Optional is present by calling getOccupation()
.
However, let's say my Person class has another optional property, but its presence can't be inferred from the value of another property; for example, a middle name. Obviously it's best for getMiddleName()
to return an empty Optional
or null if the person has no middle name, as the presence of a middle name can't really be inferred some other way.
Since I should probably be consistent in how I'm handling optional properties, it seems like I could do one of the following:
- Use
Optional
for any property that may be absent, even if it can be inferred from another property. - Add methods like
hasMiddleName()
to resolve the discrepancies (this seems like a bad idea) - Not be consistent and let the properties whose presence can be determined externally throw an exception, while the ones that are independent be wrapped in an
Optional
. - Something else?
While nulls could simplify things, it causes a problem if an optional property is an int
, which can't be nullable in Java. I could use an Integer
, but that seems like a bad idea.
What is the best way to handle these different types of optional properties?