When I looked at the articles about Java Optional, I saw a lot of people saying, "This teaching method produces only those who use ** Optional, which doesn't have a clear meaning ...", so at least I read this article as a rebellion. write.
TL; DR
For those who only know ʻis Present ()and
get ()`
When looking at the article
Null check is done with ʻOptional # isPresent ()
, and the value is fetched with ʻOptional # get ()
.
There are too many explanations like.
** Don't do that **. Then ** nothing is different from the conventional null check **. Instead of staying the same, the number of types has increased, the execution time has increased, the memory usage has increased **, and only the disadvantages have been added **. I haven't got any merit.
Optional<String> someStr = Optional.of("Hello, world!");
if (someStr.isPresent()) {
System.out.println(someStr.get()); //Don't do it
}
The first thing to keep in mind is that ** ʻOptional # get ()` should not be used **.
It's important, so I'll say it again.
** ʻDo not use Optional # get () `**. </ span>
ʻOptional # get ()` is ** a poop-like method that retrieves without worrying about whether it is null or not **. It's ** Unsafe **. It is prepared in ** only ** for "when you have to use it anyway".
<!-"It's okay because I'm checking null just before" or something like that, ** Antony Hoare will come back to this article after being fucked by a butt **. If "it's okay because I'm checking null", ** the conventional method is enough **. It's ** meaningless **. You can use ** ʻOptional # get ()` even if you forget to check ** null. ** And crash **. It's a silly story. ->
The guy who skips "I'm okay because I'm checking null just before" ** I'll come back to this article after being angry at Antony Hoare **. If "it's okay because I'm checking null", ** the conventional method is enough **. It's ** meaningless **. You can use ** ʻOptional # get ()` even if you forget to check ** null. ** And crash **. It's a silly story.
Then what should we do. ** ʻUse Optional # ifPresent () `**. This method takes a method reference as an argument. So, I'll write the lambda expression inside ... ** You don't need to know the lambda expression or the method reference, just write it like that **.
Optional<String> someStr = Optional.of("Hello, world!");
someStr.ifPresent(x -> {
System.out.println(x);
});
ʻThe method reference passed to Optional # ifPresent () is executed only when it is not ** null **. You can think of
xas a ** temporary variable **. Of course, the name is free (unless you wear it). The type is naturally
T for ʻOptional <T>
. It's best to know about lambda expressions and method references, but even if you don't know it, it should be enough because it looks like a regular if statement **.
There may be cases where you don't want to execute it only when it is not null, but you want to divide the operation according to the presence or absence of ** value **.
Optional<String> someStr = Optional.empty();
if (someStr.isPresent()) {
System.out.println(someStr.get()); //Of course don't do it
} else {
System.out.println("There was no value");
}
In that case, use ** ʻOptional # ifPresentOrElse ()` **.
Optional<String> someStr = Optional.empty();
someStr.ifPresentOrElse(x -> {
System.out.println(x);
}, () -> {
System.out.println("There was no value");
});
()-> ...
means a lambda expression with no arguments, but of course you can think of it as "a magic when you don't use a value".
Note that ʻOptional # ifPresentOrElse ()` was implemented in Java 9, so in a Java 8 environment
Optional<String> someStr = Optional.empty();
someStr.ifPresent(x -> {
System.out.println(x);
}); if (!someStr.isPresent()) {
System.out.println("There was no value");
}
There will be no choice but to.
** If possible, ʻOptional # ifPresent () should not be abused ** either. ʻOptional # map ()
, ʻOptional # flatMap () and ʻOptional # orElse ()
should often be sufficient. In the world of Optional, it is basic ** that there is no ** null check.
For example, the example of ʻOptional # ifPresentOrElse () mentioned above can be written more concisely by using these methods. If you use ʻOptional # orElse ()
to unwrap by specifying a substitute value when it was ʻempty`,
Optional<String> someStr = Optional.empty();
System.out.println(someStr.orElse("There was no value"));
This is fine. What if ʻOptional instead of ʻOptional <String>
? Then it's time for ʻOptional # map () to apply the function only when it's not ʻempty
.
Optional<Integer> someInt = Optional.empty();
System.out.println(someInt.map(x -> x.toString()).orElse("There was no value"));
It can be written more concisely if you study method references.
Optional<Integer> someInt = Optional.empty();
System.out.println(someInt.map(Object::toString).orElse("There was no value"));
Of course, if you think that one line is long, you can define a variable outside and pull it out.
For more various examples, see this article.
Since there are many self-proclaimed commentary articles that give birth to losers, ʻOptional # get ()` is not used in the first place, or the basic basic part that it is ideal not to check null itself is not well known, so it is better not to have “Optional” etc. ”, a ** tongue-in-cheek article ** will be written.
- Replace
NullPointerException
withNoSuchElementException
. The program still crashes.
If
myOPoint
does not hold the actual coordinates,myOPoint.get (). X
will throwNoSuchElementException
and crash the program. This is nothing better than the original code. That's because the programmer's goal is to avoid all crashes, not just the ones caused by theNullPointerException
.
Again, both codes are similar, and ʻOptional` is not superior to traditional referencing methods.
Well, the author of this article probably wrote such an article because there were too many defeaters. ~~ Still, there are some descriptions that he doesn't know anything about it. ~~
Due to the specifications, ** processing that can cause exceptions cannot be handled outside **.
public static int half(int even) throws Exception {
if (even % 2 == 0); else {
throw new Exception();
}
return even / 2;
}
/* ... */
Optional<Integer> someInt = Optional.of(16);
/*it can*/
try {
if (someInt.isPresent()) {
System.out.println(half(someInt.get()));
}
} catch (Exception e) {
System.out.println("Please pass an even number");
}
/*Can not*/
try {
someInt.ifPresent(x -> {
System.out.println(half(x));
});
} catch (Exception e) {
System.out.println("Please pass an even number");
}
In order to manage this, various hacks are introduced in Qiita. I think it can be managed by using Either. It ’s a monad. Well, Java isn't officially Either.