I’m trying to make a basic cache of a boolean value, and I did it like such:
private Boolean _valueCache = null;
private boolean getValue() {
try {
if (_valueCache == null) { // if cache was never filled
return _valueCache = getReader().getMyBooleanProperty(); // fill it and return the new value
}
return _valueCache; // else, return the cache
} catch (NullPointerException ex) { // getReader() returned null
return false; // that return may not be null in the future, so set nothing
}
}
Does this go against best practices? (letting a Boolean
have 3 values: true
, false
, and null
) I only want to cache this value, so I don’t want to make an entire custom HashMap that mimics this behavior with a get-or-default method. That said, I’ve never done a cache this small so I don’t know the downsides to it.
To clarify, I meant “ternary” as in “3-state”, as opposed to “binary” as in “2-state”. Sorry for any confusion.
8
You’re not doing ternary logic, you’re just using null
as a placeholder for a missing value that happens to be of type Boolean
. (Not having true
nor false
isn’t quite the same as having one of the two but not knowing which.) Using null
this way is a fairly common practice, but I wouldn’t call it a good one.
It’s unlikely to cause you problems in this particular case because it’s only used internally within a very small scope, but in general you would want to use Optional instead. Since any non-primitive variable could have null
, it’s very difficult to keep track of it in a large code base. The easiest way to avoid the issue is to not use null
in the first place.
2
While using null or using an Optional are reasonable choices, one more option would be to add an explicit second field, boolean _hasBeenRead
. Your code would look like
private boolean getValue() {
if (_hasBeenRead)
return _valueCache;
else {
// read the value and, if successful, set both _hasBeenRead and _valueCache.
}
}
Some would consider this more explicit and therefore clearer. Especially if you are using older style Java without new fangled goodies like Optional.
p.s. Whatever you do, consider whether this method need be synchronized, if the variables need to be volatile, etc…
1
The tenary logic for this should be
private Boolean _valueCache = null;
private boolean getValue() {
Boolean readerValue = getReader() == null ? false : reader.getMyBooleanProperty();
_valueCache = _valueCache == null ? readerValue : _valueCache;
return _valueCache;
}
By the way, what is the use of the NullPointer exception handled, Does the getReader() return null, Runtime exceptions like this are also not advisable
3