Should Java 8 Getters Return Optional Type

Should Java 8 getters return optional type?

Of course, people will do what they want. But we did have a clear intention when adding this feature, and it was not to be a general purpose Maybe type, as much as many people would have liked us to do so. Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result", and using null for such was overwhelmingly likely to cause errors.

For example, you probably should never use it for something that returns an array of results, or a list of results; instead return an empty array or list. You should almost never use it as a field of something or a method parameter.

I think routinely using it as a return value for getters would definitely be over-use.

There's nothing wrong with Optional that it should be avoided, it's just not what many people wish it were, and accordingly we were fairly concerned about the risk of zealous over-use.

(Public service announcement: NEVER call Optional.get unless you can prove it will never be null; instead use one of the safe methods like orElse or ifPresent. In retrospect, we should have called get something like getOrElseThrowNoSuchElementException or something that made it far clearer that this was a highly dangerous method that undermined the whole purpose of Optional in the first place. Lesson learned. (UPDATE: Java 10 has Optional.orElseThrow(), which is semantically equivalent to get(), but whose name is more appropriate.))

Should I use Java 8's Optional in my wrapper class or null when not using some attributes?

If you want to point out the fact that some of these are nullable, and the rest of the code makes use of streams/optionals etc., you can make the getters return optionals:

Optional<String> getName() {
return Optional.ofNullable(name);
}

Optional<String> getSurname() ...

etc.

You shouldn't have actual field types as Optionals. One reason being these are not serializable.

But generally the use case you described is probably more suitable for some boolean discriminatory method like isSocialSecurityProvided() that you can later use like this:

if (sw.isSocialSecutiryProvided()) {
// do something with
sw.getSocialSecurity();
} else {
//do domething with
sw.getName();
// and with
sw.getSurname();
}

Even if the whole method looks like something below, one could argue that naming it properly provides better readability of the code:

public boolean isSocialSecurityProvided() {
return socialSecurity != null;
}

Is Optional<List> bad practice?

I think the point is moot. There are two possible cases:

1. The caller needs to be aware that default values have been returned

In this case, the caller will not be able to use the orElse()/orElseGet() construct, and will have to check with isPresent(). This is no better than checking whether the list is empty.

2. The caller does not need to be aware that default values have been returned

In which case you might as well hide the implementation details behind a single List getValues() method that returns the default values in case no values were found.


As to the general applicability of using Optional<List>, I think the Brian Goetz quote from this answer says it best:

Our intention was to provide a limited mechanism for library method
return types where there needed to be a clear way to represent "no
result", and using null for such was overwhelmingly likely to cause
errors.

When it comes to lists (and collections in general), there is already a clear way to represent "no result", and that is an empty collection.

Optional value should only be accessed after calling isPresent()

The problem is warning about the get is called without checking isPresent. Which will throw NoSuchElementException if no value is present, it violates the idea of using Optional.

    @Override
public Optional<String> getUserName() {
return Optional.ofNullable(getJwt().get().getClaimAsString("preferred_username"));
}

Since getUserName() is also returning an Optional, we may use Optional#map to convert Optional<Jwt> to Optional<String>

 return getJwt().map(jwt -> jwt.getClaimAsString("preferred_username")));

map method will take care different case for us, as below:
































getJwt()jwt.getClaimAsString("preferred_username")return
emptywill not callOptioal.empty()
emptywill not callOptioal.empty()
not emptyreturn nullOptioal.empty()
not emptyreturn non null valueOptional with non null value

Optional vs if/else-if performance java 8

Don't use Optionals for conditional logic.

They were designed, to be returned from a method to indicate a potentially absent value.

Just because you can nicely chain them into a single line doesn't mean that it's understandable. Also you literally gain nothing. The performance overhead may be significant. In the worst case N objects being created and then discarded. Just stay with your "normal" if-else chains.


Instead of finding ways to make your current code more readable, take a step back and ask yourself why you need 15-20 if-else statements. Can you split some logic up? Why do you need a getter for so many different fields with potentially different types in the first place? etc.



Related Topics



Leave a reply



Submit