一、NullPointerException
NullPointerException 是程序员很典型的异常。
- 开发中我们会有许多这样的代码
if (fundProductInfo == null) {
LOGGER.error("saveFundProductInfo [存储 基金产品信息] param is null");
throw new BussinessException(Code.PARAMATERSISNULL.getValue(),"参数为空");
}
FundProductInfoDO fundProductInfoDO = convertVoToDo(fundProductInfo);
if(fundProductInfoDO.getCreateDate() == null){
fundProductInfoDO.setCreateDate(new Date());
}
- 我们会用很多代码来检查该null 值。
- 该null值本身没有意义。
二、Optional类
Java8 中添加了java.util.Optional< T >
Optional< T > 表示 T对象可能有可能没有 ,如果我们认为某个对象可能存在也可能不存在我们就可以使用Optional将其包装起来。
public class Human {
private Optional<House> house;
public Optional<House> getHouse() { return house; }
}
public class House {
private Optional<Loan> loan;
public Optional<Loan> getLoan() { return loan; }
}
public class Loan {
private String loanType;
public String getLoanType() { return loanType; }
}
- 人可能买了房子也可能没有买房子,买了房子有可能全款也有可能贷款。对于这些类我们都可以将其用Optional包装起来。Human、House中的都是用了Optional封装了,但是Loan中字段直接使用String,没有使用Optional包装,因为它是必须有值的。
三、一些基本操作
在域模型中我们可以使用Optional来对响应属性进行封装,也可以在方法的参数中使用Optional修饰的参数,这样我们可以显示这个参数有可能为null。此外在域模型中使用Optional会导致域模型无法进行序列化,因为Optional类并没有实现Serializable接口。
1、创建Optional对象
- 声明一个空的Optional
Optional<House> optHouse = Optional.empty();
- 用一个非空值创建Optional
House house = new House();
//house.set....
Optional<House> optHouse = Optional.of(house);
- 一个可以接受null的Optional
Optional<House> optHouse = Optional.ofNullable(house);
Optional<House> optHouse1 = Optional.ofNullable(null);
使用上面三种方式创建Optional对象后,我们可以使用get()方法来获取Optional变量中的值,有值得时候会返回具体的值,没有值得时候会抛出异常。如果我们创建了optHouse1 这个对象 然后进行get()操作会出现下面的异常:
Exception in thread "main" java.util.NoSuchElementException: No value present
其实我们会发现 如果get到的是个空值扔到会报错 只不过不是空指针异常了,但是并没有什么却别,所以我们应该在确定一定有值得时候使用get进行获取。
- 使用map或flatMap获取对象。
map 获取:
Optional<Loan> optLoan = Optional.ofNullable(loan);
Optional<String> name = optInsurance.map(Loan::loanType);
使用map获取对象如上,但是我们获取到的是域模型总属性的声明类型,比如Loan类中的 loanType 声明为 String 那么我们返回的就是String,如果我们获取House中的 loan属性因为声明的是Optional< Loan >所以我们获取到的就是Optional< Loan> 具体我们可以看map方法的实现:
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
flatMap获取
Human human = new Human();
human.setHouse(Optional.of(new House()));
Optional<Human> optionalPerson = Optional.ofNullable(human);
Optional<House> c = optionalHuman.flatMap(Human::getHouse);
System.out.println(c.map(Car::getInsurance));
使用flatMap获取会返回Optional< T > 类型的。具体如下:
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNonNull(mapper.apply(value));
}
}
2、相关API
isPresent()
IfPresent()
orElseThrow()、orElseGet()
orElse()
filter过滤。