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 Optional
s. 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 |
---|---|---|
empty | will not call | Optioal.empty() |
empty | will not call | Optioal.empty() |
not empty | return null | Optioal.empty() |
not empty | return non null value | Optional with non null value |
Optional vs if/else-if performance java 8
Don't use Optional
s 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
What Is "String Args[]"? Parameter in Main Method Java
Java.Net.Socketexception: Connection Reset
Want Current Date and Time in "Dd/Mm/Yyyy Hh:Mm:Ss.Ss" Format
Random Errors When Changing Series Using Jfreechart
How to Unescape a Java String Literal in Java
Dependency Injection With Jersey 2.0
Difference Between Javac and the Eclipse Compiler
Removing Whitespace from Strings in Java
Real Differences Between "Java -Server" and "Java -Client"
Convert String to Double in Java
Syntax For Creating a Two-Dimensional Array in Java
What Do ^ and $ Mean in a Regular Expression
How to Call One Constructor from Another in Java
Variable Used in Lambda Expression Should Be Final or Effectively Final
How to Use Wait and Notify in Java Without Illegalmonitorstateexception