Java8学习【004】

一、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对象
  1. 声明一个空的Optional
Optional<House> optHouse = Optional.empty();
  1. 用一个非空值创建Optional
House house = new House();
//house.set....
Optional<House> optHouse = Optional.of(house);
  1. 一个可以接受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进行获取。

  1. 使用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过滤。


发布了122 篇原创文章 · 获赞 32 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/YangzaiLeHeHe/article/details/99580833