Java8引入了Optional类来解决NullPointerException的问题。学习好Optional的使用方式,使我们的代码更加健壮。
示例类:
class Insurance {
private String name;
public String getName() {
return name;
}
}
class Car {
private Optional<Insurance> insurance;
public Optional<Insurance> getInsurance() {
return insurance;
}
}
public class Person {
private Optional<Car> car;
public Optional<Car> getCar() {
return car;
}
}
1.创建Optional对象
1.1 声明一个空Optional
Optional<Car> optCar = Optional.empty();
1.2 依据一个非空值创建Optional
Car car = new Car();
Optional<Car> optCar2 = Optional.of(car);
1.3 可接受null的Optional
Car car2 = null;
Optional<Car> optCar3 = Optional.ofNullable(car2);
2. 从Optional对象中提取和转换值
Insurance insurance = new Insurance();
Optional<Insurance> optInsurance = Optional.ofNullable(insurance);
Optional<String> name = optInsurance.map(Insurance::getName);
System.out.println(name);
// output
// Optional.empty
3. 在Optional对象中flatMap的使用方式
Optional<Person> person1 = Optional.ofNullable(person);
String insuranceName = person1.flatMap(Person::getCar)
.flatMap(Car::getInsurance)
.map(Insurance::getName)
.orElse("Unknown");
4. 序列化遇到的问题
在程序中使用了某些要求序列化的库或者框架,在域模型中使用Optional,有可能引发应用程序故障。这是由于Optional类设计时就没有特别考虑将其作为类的字段使用,所以它也并未实现Serializable接口。
5. filter的用法
Insurance insurance = new Insurance();
Optional<Insurance> optInsurance = Optional.ofNullable(insurance);
optInsurance.filter(ins->"example".equals(ins.getName()))
.ifPresent(x->System.out.println("OK"));
基础类型的Optional对象(OptionalInt、OptionalLong及OptionalDouble),避免使用,因为基础类型的Optional不支持map、flatMap以及filter方法。
6 Optional的实战中的用法
6.1 用Optional封装可能为null的值
Optional<Object> value = Optional.ofNullable(map.get("key"));
6.2 异常与Optional的对比
public static Optional<Integer> stringToInt(String s) {
try {
return Optional.of(Integer.parseInt(s));
} catch (NumberFormatException e) {
e.printStackTrace();
return Optional.empty();
}
}
6.3 Optional整合
Optional.ofNullable(props.getProperty(name))
.flatMap(OptionalUtils::stringToInt)
.filter(i -> i>0)
.orElse(0);
7 Optional类的用法
方法 | 描述 |
---|---|
empty | 返回一个空的Optional实例 |
filter | 如果值存在并且满足提供的谓词,就返回包含该值的Optional对象;否则返回一个空的Optional对象 |
flatMap | 如果值存在,就对该值执行提供的mapping函数调用,返回一个Optional类型的值,否则就返回一个空的Optional对象 |
get | 如果值存在,就将被Optional封装的值返回,否则抛出一个NoSuchElementException异常 |
ifPresent | 如果值存在,就执行使用该值的方法调用,否则什么也不做 |
isPresent | 如果值存在就返回true,否则返回false |
map | 如果值存在,就对该值执行提供的mapping函数调用 |
of | 将指定用Optional封装之后返回,如果该值为null,则抛出一个NullPointerException异常 |
ofNullable | 将指定值用Optional封装之后返回,如果该值为null,则返回一个空的Optional对象 |
orElse | 如果有值则将其返回,否则返回一个默认值 |
orElseGet | 如果有值则将其返回,否则返回一个由指定的Supplier接口生成的值 |
orElseThrow | 如果有值则将其返回,否则抛出一个由指定的Supplier接口生成的异常 |