What is the difference between Optional.ofNullable() and `Optional.of() - java

First of all, I know the difference between the two methods.
Optional.of : Used to ensure that there is no null, if null is entered, nullPointExcepction
Optional.ofNullable : may or may not be null. Used to respond flexibly.
So, if I add orElseThrow(() -> new NullPointerException("null data")) to this, will it end up being the same?
I want to throw an error with explicit content.
So I get Optional.ofNullable(data).orElseThrow(() -> new NullPointerException("null data")))
use it as Is this pointless behaviour?
Optional.of(data).orElseThrow(() -> new NullPointerException("null data")))
I think this is also possible, but I'm just using ofNullable() to make the code look consistent.
to sum it up,
In the end, if you add orElseThrow(nullPoint)
Are of or ofNullable the same result?
then rather
Is of.orElseThrow better?

to sum it up, In the end, if you add orElseThrow(nullPoint) Are of or ofNullable the same result?
No. To see this, simply look at the types.
public static <T> Optional<T> of(T value);
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
throws X extends Throwable;
Optional.of returns an Optional<T>, where orElseThrow is going to leave you with a T. So Optional.ofNullable(x).orElseThrow(...) is really just a very roundabout
if (x == null) {
throw new NullPointerException(...);
}
You're not actually doing anything with the Optional, just making one and discarding it in a really verbose way. So if that's your intent, just do an explicit null check; there's no need at all for Optional.
Which raises the question of why we would use of or ofNullable. With the introduction of Optional, there are now two ways to represent the concept of "this value might not exist" in Java: null and Optional.empty(). People on the Internet will argue till the end of time about which is better and when you should use which one (I have strong opinions on this which I'll refrain from sharing here, since it's not what you asked), but the point is that there are two different ways to do it.
For the rest of this post, I'll borrow a bit of notation from Kotlin and write T? to mean "a T value which might be null". It's not valid Java notation, but it gets the point across. So if we want to represent "A T which may or may not exist" in Java, we can use either Optional<T> or T?.
If we want to go from T? to Optional<T>, that's what Optional.ofNullable is for. It says "If the thing is null, give me Optional.empty(); otherwise give me the thing in an Optional". To go the other way, we can use Optional.orElse(null), which says "If I have a T, give it to me, otherwise show me null". So now we have a way to convert between the two approaches. So what's Optional.of for?
You should view Optional.of as an assertion of sorts. If Java had nullable types like Kotlin, then the difference would be something like
public static <T> Optional<T> of(T value);
public static <T> Optional<T> ofNullable(T? value);
That is, ofNullable expects that its value might be null. of is already assuming that it's not. Optional.of should be thought of an assertion that the value you're giving it is not null. If that assertion fails, we throw NullPointerException immediately rather than letting errors propagate to other parts of the program. If you're calling Optional.of and recovering from the NullPointerException it throws[1], then you are doing something very wrong. That function is an assertion we were dealing with non-null data to begin with, and if that assertion fails then your program should fail immediately with a good stack trace.
It sounds like, based on your use case, you have a value that might be null. In that case, Optional.ofNullable makes sense; it's prepared to handle the use case. If you want to throw a custom exception, you should do a null check beforehand (since you're the one handling the null, not Optional) and then call Optional.of. Or, of course, you can just do an old-fashioned null check and not use Optional at all, if you're planning to extract it anyway with orElseThrow. Certainly, the pipeline Optional.ofNullable(value).orElseThrow(...) in one line would be a code smell.
[1] Note that I say "recovering from", not "catching". A nice top-level catch (Exception exc) which logs all errors is perfectly acceptable and generally a good idea in larger applications. But if you're doing catch (NullPointerException exc) { return 0; } or something like that then you need to reconsider which Optional method you should be using.

First of all, I know the difference between the two methods.
Optional.of : Used to ensure that there is no null, if null is
entered, nullPointExcepction
Optional.ofNullable : may or may not be null. Used to respond
flexibly.
There's a clear point of misunderstanding.
The purpose of Optional.of() is not "to ensure that there is no null". It is not meant to be used as an assertion that a value that was passed into it is non-null. For such a validation you can use Objects.requireNonNull(), it'll either throw an NPE, or will return you a non-null value.
In order to be on the same page, the first important thing you have to keep in mind is that optionals were introduced in the JDK for only one particular purpose - to serve as a return type. Any other cases when optional is utilized as a parameter-type, or a field-type, or when optional objects are being stored in a collection isn't considered to be a good practice. As well, as creating an optional just in order to chain methods on it or to hide a null-check is considered to be an antipattern.
Here is a couple of quotes from the answer by #StuartMarks, developer of the JDK:
The primary use of Optional is as follows:
Optional is intended to
provide a limited mechanism for library method return types where
there is a clear need to represent "no result," and where using null
for that is overwhelmingly likely to cause errors.
A typical code smell is, instead of the code using method chaining to
handle an Optional returned from some method, it creates an Optional
from something that's nullable, in order to chain methods and avoid
conditionals.
I also suggest you to have a look at this answer to the question "Should Optional.ofNullable() be used for null check?", also by Stuart Marks.
With all that being said, combination Optional.of().orElseThrow() is both wrong and pointless:
If provided data is null method of() will raise an NPE and orElseThrow() will not be executed (i.e. its exception will get never be fired).
You're abusing the optional by creating an optional object not in order to return a nullable variable wrapped by it, but to hide the null-check (take a look at the quote above). That obscures the purpose of your code. You can use Objects.requireNonNull() instead to throw an exception if the given value must not be null or requireNonNullElse() to provide a default value.
For the same reason, you shouldn't use Optional.ofNullable().orElseThrow() at the first place.
Optional is like a Box
You might think of optional is if it is a parcel. When you need to send something, you go to the post office (i.e. returning from the method), where the thing that has to be sent is being placed into a box. When somebody (i.e. the caller) receives the parcel, it is being immediately unpacked. That is the whole lifecycle of the box called Optional.
When, according to the logic of your application, an object required to be returned from the method should not be null - use Optional.of(). It'll either send a parcel successfully or will emphasize that there's a problem by raising a NullPointerException.
If the given object is nullable by its nature, i.e. null isn't an abnormal case, then use Optional.ofNullable(), it'll fire either a box containing the object or an empty box.
And the caller (i.e. method that invokes the method returning an optional) is the one who has to unpack the box using a variety of tools that optional provides like orElseThrow(), orElseGet(), ifPresent(), etc.

Related

Could be in Optional really anything

I found implemented this code (method where this part of code is used is returning Optional<File>, this part of code had to be added for verification if values are correct and case can be saved):
if (!CaseChecker.checkValues(case)) {
return Optional.of(new File("FALSE"));
}
When I asked the person, why he is returning something like this. The answer was "Optional can contain any value". To be honest I don't agree with this, because type of Optional is for some reason. So I wanted to confirm if Optional can be really anything and if yes, then what's the reason to write Optional type.
The whole point of Optional is to avoid the situation where you return a bogus value (like null, or like returning -1 from String.indexOf in order to indicate it didn't find anything), putting the responsibility on the caller to know what is bogus and to know to check for it. Returning Optional lets the caller know it needs to check whether a valid result came back, and it takes away the burden of the caller code needing to know what return values aren't valid.
Optional was never meant as a wrapper for a bogus value.
And yes you can return anything. The api doesn't stop you from doing nonsensical things.
Also consider that flatMap doesn't know what to do with this weird thing, it will treat the contents as nonempty. So now how you can use this value is limited. You have a multistage validation process where it might be something you can handle with operations chained together using flatMap, but this fake file has made that harder. It's limited your options.
Return Optional.empty() if you don't have a valid value to return.

I need an advice on null safety in Java

I've been reading articles on beeing null safe in java, and how it's bad to return null, or of that sin, that is passing null as an argument. I get that it simplifies life, and people don't always read documentation, so they don't know wheather a method can return null, or if null can be passed to it. Annotations seem to just pollute the code, and there is no Kotlin-like null safety mechanism. In my current project I try to design everything in such a manner, that null is almost unnecessary, at least for the end-user.
I want to create a change listener (something like javafx.beans.value.ChangeListener), such that i can pass a previous and a current value to the changed() method. The thing is, I want it to be null safe, so I don't want to ever pass a null as an argument, even though it can change from no value to some value, or from some value to no value. I could add two additional methods for that situation and have something like:
public inteface ChangeListener<T> {
void valueSet(T current);
void valueChanged(T previous, T current);
void valueCleared(T previous);
}
This approach seems excessive though. I could also use
java.util.Optional<T> as arguments, but that adds additional boxing:
public inteface ChangeListener<T> {
void changed(Optional<T> previous, Optional<T> current);
}
Is there a more elegant option? Or should I force user to use some sort of a Null Object Pattern? Although that will create problems with the need to extend some classes. I could also stop caring, specify in the documentation what will happen if null is used, and let the user find the source of all the NullPointerExceptions.
Be a bit careful when people tell you "XYZ considered harmful". I've seen people do away with constructors altogether in favour of factory methods (such as Optional.of(...)), but as with everything, there's no single correct answer.
You seem to be struggling with trying to achieve several things (using simple code, having only one method in the listener, not using null values) that are mutually exclusive. So stop worrying and focus on what's important.
If your API users are idiots, and they don't read documentation, that's not really your problem. Null is not something dirty; it means "undefined". What is dubious is to use null if something unexpected happened, like "file not found", which should ideally be dealt with via an exception.
If "undefined" is a correct representation of an unset value in your API, then there's nothing wrong with using null.

java.util.Objects vs Optional which is preferable?

The java.util.Objects class was extended with a number of new methods
Objects#requireNonNullElse
respectively
Objects#requireNonNullElseGet() in Java-9.
Both will return the first argument if it is non-null and otherwise returns the non-null second argument or the non-null value of supplier.get()
jshell> String nullStr = null;
nullStr ==> null
jshell> Objects.requireNonNullElse(nullStr,"lorem ipsum");
$13 ==> "lorem ipsum"
jshell> Objects.requireNonNullElseGet(nullStr,() -> "lorem ipsum");
$14 ==> "lorem ipsum"
But the new functionality overlaps with already existing in the Optional class Optional#orElse and Optional#orElseGet
jshell> Optional.ofNullable(nullStr).orElse("lorem ipsum");
$17 ==> "lorem ipsum"
jshell> Optional.ofNullable(nullStr).orElseGet(() -> "lorem ipsum");
$18 ==> "lorem ipsum"
The only difference between new methods in Objects and corresponding Optional methods is that second argument or value of supplier must be non-null otherwise Objects throws NPE:
jshell> Objects.requireNonNullElseGet(nullStr,() -> null);
| java.lang.NullPointerException thrown: supplier.get()
| at Objects.requireNonNull (Objects.java:246)
| at Objects.requireNonNullElseGet (Objects.java:321)
| at (#15:1)
jshell> Objects.requireNonNullElse(nullStr,null);
| java.lang.NullPointerException thrown: defaultObj
| at Objects.requireNonNull (Objects.java:246)
| at Objects.requireNonNullElse (Objects.java:301)
| at (#16:1)
versus Optional
jshell> Optional.ofNullable(nullStr).orElse(null);
$19 ==> null
jshell> Optional.ofNullable(nullStr).orElseGet(() -> null);
$20 ==> null
Why haven't the JDK developers updated existing methods in Optional
class?
Why haven't they introduced a new method (which will thrown
NPE if second argument is null) to Optional class?
What should we use now Optional or Objects?
Do new methods make Objects more preferable than Optional since they
will throw NPE immediately and not later on somewhere in the code
like with Optional?
If I have a legacy code, something like:
String str = null;
String result = str == null ? "other string" : str;
Which is just a simple check inside a method. And I would like to re-factor it using latest language features. Now having in mind the difference between Optional.orElse and Objects.requireNonNullOrElse which is preferable?
result = Optional.ofNullable(str).orElse("other string");
or
result = Objects.requireNonNullOrElse(str,"other string);
The shortest answer to your question "which is preferable?" is the all-time developer favorite "it depends" 😜 because Objects::requireNonNullElse and Optional cover different use cases.
The Two Alternatives
Before answering your questions I want to give some background on the two alternatives.
Objects::requireNonNullElse
Objects::requireNonNull makes sure that the result of the call is never null (hence the name). It is usually used to succinctly verify constructor or method arguments and allows readers to verify with a glance that the variable to which the return value is assigned can not be null.
So it would not only be weird for Objects::requireNonNullElse to suddenly allow null, it would also be borderline useless because:
// if requireNonNullGet would allow null as second argument,
// the following is true for all x (including null)
Objects.requireNonNullElse(x, null) == x
You might argue that it is different for requireNonNullElseGet because that might call a function that, depending on some state, might return null or not. That's true and I assume it was considered but the requireNonNull... API would be really weird if one of the three cases might actually allow the final result of the call to be null even though the name says required non null.
Optional
Optional was designed as a return argument in cases where returning null is very likely to cause NPEs (like for a Stream's terminal operation, where it was first used). Although some developers prefer to use it in more cases (compare Stephen Colebourne's pragmatic approach and my strict approach) no one really proposes using it as in your demonstration:
Optional.ofNullable(nullStr).orElse(null);
Optional.ofNullable(nullStr).orElseGet(() -> null);
Optional is a way to express in the type system that something might be missing - it is not meant as an alternative to if-null-checks. In that sense orElse or orElseGet are backdoors out of Optional back into the world of nullable types and sometimes null is just what you want to use if something's not there, so it makes sense for them to accept null as an argument (or the supplier's result).
Your Questions
Now we have what we need to answer your questions:
Why haven't the JDK developers updated existing methods in Optional class?
Conceptually that would go against what Optional should be used for. But, as others have mentioned, this would be a backwards incompatible change as calls to orElse(null) would suddenly throw exceptions.
Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
APIs are only extended if considerable improvements of existing code can be expected. I don't see that here. In many cases orElse gets an argument that the caller creates specifically as an alternative for empty optionals - there is rarely a need to make an extra check to verify it's not null. If you really have to, call orElse(requireNonNull(x)).
What should we use now Optional or Objects?
If you have a variable (be it local, an argument or a field) and you want to make sure it's not null, use Objects. If you want to return something, which may be null consider wrapping it in Optional. Be suspicious of code that creates an Optional (as opposed to getting one form a call) and unwraps it at the end of the same chain.
Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
As I'm sure is clear by now, they cover different use cases. But let me address "and not later on somewhere in the code like with Optional": Whatever you do, make sure to check your desired nullablity property (can be null or not) in your code. Don't return something that you assume can not be null but it turns out to be because you didn't check. If that happens, it's not Optional's fault.
If I have a legacy code, something like:
String str = null;
String result = str == null ? "other string" : str;
Definitely Objects.requireNonNullOrElse(str,"other string"); and consider using static imports to make it more readable.
Why haven't the JDK developers updated existing methods in Optional class?
Because that would introduce a breaking change that would break many existing programs, and because the method should allow getting null if desired.
Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
Probably because that would make the API more convoluted and bloated for no significant advantage. You can still wrap the result with requireNonNull if you want to ensure your code doesn't return null unexpectedly.
What should we use now Optional or Objects?
If you need to extract a value out of an optional returned by a method, then use Optional's method. If you want to ensure preconditions are respected for the argument of a method that should not be null, use Object.requireXxx. The JDK designers have never advocated the use of Optional just to wrap a value and check for null. Optional is for return values.
Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
See previous points: you don't use these methods to do the same thing.
The point is: those two method signatures are clearly different:
public static <T> T requireNonNullElse(T obj, T defaultObj)
vs.
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
The javadoc for the second method reads:
Returns the first argument if it is non-null and otherwise returns the non-null value of supplier.get().
In other words: it uses the supplier that you provide to it here.
So, the answer is: you use the second version for situations where you want to work with a supplier; and otherwise you simply take the "more simple" version of that method that takes the "less complicated" parameter.
The reasoning behind that: when you decide between two options, you prefer that one that is easier/"less reader surprising" to use. In other words: why would you want to provide a supplier, when you can go without.
Regarding the usage of Optionals - keep in mind that their main goal was to be used for return types; not as method parameters (see here for further reading).
Then: updating existing methods in a class delivered "to the field" is almost always a no-go. You absolutely do not want to change the semantics of something that is already out in the open and used by your customers; assuming specific semantics.
Q. Why haven't the JDK developers updated existing methods in Optional class?
A. Because Optional class was designed to avoid NPE.
Q. Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
A. The same answer.
Q. What should we use now Optional or Objects?.
A. Both. Objects for simple "not null" checkings and Optional for chain operations like map, flatMap, `filter'.
Q. Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
A. Depends on situation. If you already have Optional as return value of some method then it is preferable to use Optional.
So the main point is if you like using ifs for checking for null or not. If you have a method that can take arguments that can be of null value, It would make more sense to use Objects. The only reasonable place to use Optional is to verify a call to a method that returns optional result.
Developers wanted to use more functional way of checking for null values, so the where using the construct Optional.ofNullable for that purpose, which wasn't a good practice, because it was creating garbage.

What to do in findXY method if no such object exists?

Assume I have a Java method
public X findX(...)
which tries to find an Object of type X fulfilling some conditions (given in the parameters). Often such functions cannot guarantee to find such an object. I can think of different ways to deal with this:
One could write an public boolean existsX(...) method with the same signature which should be called first. This avoids any kind of exceptions and null handling, but probably you get some duplicate logic.
One could just return null (and explain this in javadoc). The caller has to handle it.
One could throw a checked exception (which one would fit for this?).
What would you suggest?
The new Java 8 Optional class was made for this purpose.
If the object exists then you return Optional.of(x) where x is the object, if it doesn't then return Optional.empty(). You can check if an Optional has an object present by using the isPresent() method and you can get the object using get().
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
If you can't use Optional I would go with option 2.
In the case of 1. You'd be doing double work, first you have to check if X exists, but if it does, you're basically discarding the result, and you have to do the work again in findX. Although the result of existsX could be cached and checked first when calling findX, this would still be an extra step over just returning X.
In the case of 3. To me this comes down to usability. Sometimes you just know that findX will return a result (and if it doesn't, there is a mistake somewhere else), but with a checked exception, you would still have to write the try and (most likely empty) catch block.
So option 2 is the winner to me. It doesn't do extra work, and checking the result is optional. As long as you document the null return, there should be no problems.
Guava (potentially other libraries, too) also offers an Optional class that might be worth exploring if your project uses Guava since you seem to not use Java 8.
If you
don't/can't/won't use Java 8 and its accompanying Optional type
don't want another library dependency (like Guava) for a single class implementation
but
you want something more robust than methods that can return null for which you have to have a check in all consumers (which was the standard before Java 8)
then writing your own Optional as an util class is the easiest option.

Defensive Programming: Guidelines in Java

I’m from a .NET background and now dabbling in Java.
Currently, I’m having big problems designing an API defensively against faulty input. Let’s say I’ve got the following code (close enough):
public void setTokens(Node node, int newTokens) {
tokens.put(node, newTokens);
}
However, this code can fail for two reasons:
User passes a null node.
User passes an invalid node, i.e. one not contained in the graph.
In .NET, I would throw an ArgumentNullException (rather than a NullReferenceException!) or an ArgumentException respectively, passing the name of the offending argument (node) as a string argument.
Java doesn’t seem to have equivalent exceptions. I realize that I could be more specific and just throw whatever exception comes closest to describing the situation, or even writing my own exception class for the specific situation.
Is this the best practice? Or are there general-purpose classes similar to ArgumentException in .NET?
Does it even make sense to check against null in this case? The code will fail anyway and the exception’s stack trace will contain the above method call. Checking against null seems redundant and excessive. Granted, the stack trace will be slightly cleaner (since its target is the above method, rather than an internal check in the HashMap implementation of the JRE). But this must be offset against the cost of an additional if statement, which, furthermore, should never occur anyway – after all, passing null to the above method isn’t an expected situation, it’s a rather stupid bug. Expecting it is downright paranoid – and it will fail with the same exception even if I don’t check for it.
[As has been pointed out in the comments, HashMap.put actually allows null values for the key. So a check against null wouldn’t necessarily be redundant here.]
The standard Java exception is IllegalArgumentException. Some will throw NullPointerException if the argument is null, but for me NPE has that "someone screwed up" connotation, and you don't want clients of your API to think you don't know what you're doing.
For public APIs, check the arguments and fail early and cleanly. The time/cost barely matters.
Different groups have different standards.
Firstly, I assume you know the difference between RuntimeExceptions (unchecked) and normal Exceptions (checked), if not then see this question and the answers. If you write your own exception you can force it to be caught, whereas both NullPointerException and IllegalArgumentException are RuntimeExceptions which are frowned on in some circles.
Secondly, as with you, groups I've worked with but don't actively use asserts, but if your team (or consumer of the API) has decided it will use asserts, then assert sounds like precisely the correct mechanism.
If I was you I would use NullPointerException. The reason for this is precedent. Take an example Java API from Sun, for example java.util.TreeSet. This uses NPEs for precisely this sort of situation, and while it does look like your code just used a null, it is entirely appropriate.
As others have said IllegalArgumentException is an option, but I think NullPointerException is more communicative.
If this API is designed to be used by outside companies/teams I would stick with NullPointerException, but make sure it is declared in the javadoc. If it is for internal use then you might decide that adding your own Exception heirarchy is worthwhile, but personally I find that APIs which add huge exception heirarchies, which are only going to be printStackTrace()d or logged are just a waste of effort.
At the end of the day the main thing is that your code communicates clearly. A local exception heirarchy is like local jargon - it adds information for insiders but can baffle outsiders.
As regards checking against null I would argue it does make sense. Firstly, it allows you to add a message about what was null (ie node or tokens) when you construct the exception which would be helpful. Secondly, in future you might use a Map implementation which allows null, and then you would lose the error check. The cost is almost nothing, so unless a profiler says it is an inner loop problem I wouldn't worry about it.
In Java you would normally throw an IllegalArgumentException
If you want a guide about how to write good Java code, I can highly recommend the book Effective Java by Joshua Bloch.
It sounds like this might be an appropriate use for an assert:
public void setTokens(Node node, int newTokens) {
assert node != null;
tokens.put(node, newTokens);
}
Your approach depends entirely on what contract your function offers to callers - is it a precondition that node is not null?
If it is then you should throw an exception if node is null, since it is a contract violation. If it isnt then your function should silently handle the null Node and respond appropriately.
I think a lot depends on the contract of the method and how well the caller is known.
At some point in the process the caller could take action to validate the node before calling your method. If you know the caller and know that these nodes are always validated then i think it is ok to assume you'll get good data. Essentially responsibility is on the caller.
However if you are, for example, providing a third party library that is distributed then you need to validate the node for nulls, etcs...
An illegalArugementException is the java standard but is also a RunTimeException. So if you want to force the caller to handle the exception then you need to provided a check exception, probably a custom one you create.
Personally I'd like NullPointerExceptions to ONLY happen by accident, so something else must be used to indicate that an illegal argument value was passed. IllegalArgumentException is fine for this.
if (arg1 == null) {
throw new IllegalArgumentException("arg1 == null");
}
This should be sufficient to both those reading the code, but also the poor soul who gets a support call at 3 in the morning.
(and, ALWAYS provide an explanatory text for your exceptions, you will appreciate them some sad day)
like the other : java.lang.IllegalArgumentException.
About checking null Node, what about checking bad input at the Node creation ?
I don't have to please anybody, so what I do now as canonical code is
void method(String s)
if((s != null) && (s instanceof String) && (s.length() > 0x0000))
{
which gets me a lot of sleep.
Others will disagree.

Categories

Resources