Reputation: 318
I have a Record class as follows
class Record {
String name;
Object value;
public void setValue(Object value) { this.value = value; }
}
If no value was set to the value
field then it would be null
. It is also possible that null
was explicitly set using the setter i.e new Record().setValue(null)
.
Since explicitly setting the value as null
has meaning in my application, I want to track whether the null value was explicitly set by user or is just an implicit null. What is the best way and the proper way to do it?
The solutions I came up with were,
Object value = new Undefined();
and perform instance check later. Here Undefined
is an internal dummy class.Optional<Object> value;
and have the setter as public void setValue(Object value) { this.value = Optional.ofNullable(value); }
If this was JavaScript, it has undefined
built in the language itself. What is the best way to do this Java?
Upvotes: 0
Views: 5287
Reputation: 719576
What is the best way and the proper way to do it?
There is no single "best" or "proper" way to do this, though it is probably a bad idea to try to distinguish different causes or kinds of null
.
Here are some of the alternatives.
Avoid the problem by making null
an illegal value; e.g.
public void setValue(Object value) {
if (value == null) {
throw new NullPointerException("Value cannot be null");
} else {
this.value = value;
}
}
Use Optional<Object>
.
Use the Null Object Pattern.
Use zero length arrays and (immutable) empty collections rather than null
arrays and collections. (The "null
means empty" optimization is a bad idea. It makes your code more complicated and more NPE prone and the space saving is minuscule.)
Avoid the problem by insisting that the field is initialized to a non-null value. This could be done using the Builder Pattern, or using a constructor that insists that the supplied value for value
not null.
Use a special value to mean "this field has not been initialized"; e.g.
private static final Object UNINITIALIZED = new Object();
private Object value = UNINITIALIZED;
public void getValue() {
if (value == UNINITIALIZED) {
throw new UninitializedFieldException("Value is uninitialized");
} else {
return value;
}
}
Notes:
value
field needs to be private
and the getter needs to throw an exception if the field is "uninitialized.Use a boolean to denote that the field has not been initialized.
Upvotes: 2
Reputation: 1157
I think considering null
value as user entry isn't the best solution since later on, you can't differentiate a null
coming from the user from a null
field that wasn't set programmatically. (i.e. If your client needs to update the record, you will not be able to distinguish whether he sets the value to null
or he doesn't want to update it, hence you can overwrite a previous value).
So, if I were in you place, I would replace the null
with some meaningful object value.
Upvotes: 0