6

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

3 Answers 3

7

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
  • 1
    The Optional class looks promising! If only I weren't forced to use Java 1.6...
    – Ky -
    Commented Mar 5, 2015 at 16:14
  • 2
    @BenC.R.Leggiero Guava has an Optional implementation as well and should work with 1.6. It's also not hard to implement yourself.
    – Doval
    Commented Mar 5, 2015 at 16:18
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
  • Good point about the volatile and synchronized status! This is for Android, so I'm not entirely sure what threads will need this or when.
    – Ky -
    Commented Mar 9, 2015 at 13:13
-3

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
  • <sarcasm mode on>That line of code is too short - somebody might actually understand it.</sarcasm mode on>
    – user949300
    Commented Mar 7, 2015 at 0:10
  • Thanks for your input! Sorry, I wasn't clear. I don't need help on how to use the ternary operators ?:, but on whether this 3-state Boolean is a good idea.
    – Ky -
    Commented Mar 9, 2015 at 13:16
  • Also, the getReader() method (not made/controlled/modifiable by me) contains a conditional throw new NullPointerException() in it, so the try/catch is necessary, anyway.
    – Ky -
    Commented Mar 9, 2015 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.