Summary: Optional is not a replacement for the null keyword, but provides a more elegant implementation of null judgment
NullPointException can be said to be an exception that all java programmers have encountered. , although Java has tried to free programmers from the suffering of pointers from the beginning of its design, pointers do actually exist, and Java designers can only make pointers simpler and easier to use in the Java language, but cannot completely Remove it, so we have the keyword
null
that we see every day.
Null pointer exception is a runtime exception. For this type of exception, if there is no clear handling strategy, then the best practice is to let the program hang up early. However, in many scenarios, developers do not have specific Handling strategy, but not aware of the existence of null pointer exception at all. When an exception does occur, the processing strategy is also very simple. Just add an if statement judgment where the exception exists. However, such a response strategy will cause more and more null judgments to appear in our program. We know a good Program design should minimize the occurrence of the null keyword in the code, and the
Optional
class provided by java8 not only reduces NullPointException, but also improves the beauty of the code. But first we need to make it clear that it is not a replacement for the
null
str.length()
if(null == str) { // Null pointer determination
return 0;
}
return str.length();
If the Optional class is used, implement As follows:
return Optional.ofNullable(str).map(String::length).orElse(0);
Optional code is relatively concise. When the amount of code is large, we can easily forget it. Perform null determination, but using the Optional class will avoid such problems.
Create an empty object
Optional
The above example code calls the
empty()
Optional
Create object: empty is not allowed
Optional provides a method
of()
NullPointException
Optional
##Create object: allowed to be empty
If you are not sure whether there is a possibility of null value in the parameter passed in, you can use Optional's
ofNullable()
Optional
2. Streaming processing
For demonstration, we designed a
User
/** * @author: zhenchao.Wang 2016-9-24 15:36:56 */ public class User { /** 用户编号 */ private long id; private String name; private int age; private Optionalphone; private Optional email; public User(String name, int age) { this.name = name; this.age = age; } // 省略setter和getter }
Mapping: map and flatMap
Mapping is an operation that converts input into another form of output. For example, in the previous example, we input a string and output is the length of the string, which is a kind of implicit reflection, which we can achieve by using method
map()
String name = Optional.ofNullable(user).map(User::getName).orElse("no name");
In this way, when the input parameter user is not empty, its name will be returned, otherwise
no name
long phone = optUser.map(User::getPhone).map(Optional: :get).orElse(-1L);
In fact, at this time, a better way is to use flatMap to get the results we want in one step:
long phone = optUser.flatMap(User:: getPhone).orElse(-1L);
flapMap can flatten each stream returned by the method into one stream, which will be detailed in the next article dedicated to stream processing.
Filter: filter
filiter, as the name suggests, is a filtering operation. We can pass the filtering operation as a parameter to this method to achieve the purpose of filtering. Add what we want To screen adults over 18 years old, you can achieve the following:
optUser.filter(u -> u.getAge() >= 18).ifPresent(u -> System.out.println("Adult:" + u));
The default behavior is when Optional does not meet the conditions The operation to perform, such as the
orElse()
就是一个默认操作,用于在Optional对象为空时执行特定操作,当然也有一些默认操作是当满足条件的对象存在时执行的操作。
get()
get用于获取变量的值,但是当变量不存在时则会抛出
NoSuchElementException
,所以如果不确定变量是否存在,则不建议使用
orElse(T other)
当Optional的变量不满足给定条件时,则执行orElse,比如前面当str为null时,返回0。
orElseGet(Supplier extends X> expectionSupplier)
如果条件不成立时,需要执行相对复杂的逻辑,而不是简单的返回操作,则可以使用orElseGet实现:
long phone = optUser.map(User::getPhone).map(Optional::get).orElseGet(() -> { // do something here return -1L; }); orElseThrow(Supplier extends X> expectionSupplier)
与get()方法类似,都是在不满足条件时返回异常,不过这里我们可以指定返回的异常类型。
ifPresent(Consumer
)
当满足条件时执行传入的参数化操作。
Optional是一个final类,未实现任何接口,所以当我们在利用该类包装定义类的属性的时候,如果我们定义的类有序列化的需求,那么因为Optional没有实现Serializable接口,这个时候执行序列化操作就会有问题:
public class User implements Serializable{ /** 用户编号 */ private long id; private String name; private int age; private Optionalphone; // 不能序列化 private Optional email; // 不能序列化
不过我们可以采用如下替换策略:
private long phone; public OptionalgetPhone() { return Optional.ofNullable(this.phone); }
看来Optional在设计的时候就没有考虑将它作为类的字段使用~
以上就是Java8 新特性之 Optional 类 的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!