Optional出现的目的主要是为了解决日常开发中的空指针异常:NPE,NullPointerException
以前经常这么判断:
if (null != person) {
Address address = person.getAddress();
if (null != address) {
}
}
api解释:
Optional是一个容器对象, 容器对象可能包含,也可能不包含一个非空的值。里面有可能是一个实实在在的对象,有可能就是一个空。如果容器对象里面的这个值存在的话,isPresent()方法就会返回true,get()方法就会返回这个值本身。这是一个基于值的这么一个对象,不要在Optional对象上使用比如==等操作。
基于值的类的解释:基于值的对象都是final的,都是不能被继承的,而且是没有公有的构造方法的,构造方法是私有的,只能通过类内部提供的工厂方法获取其对象。
对其类内部提供的工厂方法进行详细解释:
1、empty():返回一个容器里面为空的Optional对象,也就是说这个容器对象里面的那个值value肯定是为空的(null);
2、of():它会直接new一个Optional,这个Optional容器里面的value肯定是有值的,调用of()方法的时候,调用者一定要确保传进来的参数value是有值,否则会直接抛出异常。
3、ofNullable():构造出来一个容器里面value可能为空,也可能不为空的这么一个Optional对象。
剩下的方法:
4、isPresent():判断这个容器里面的那个value是否存在,是否为null。
5、get():直接取出来容器里面的那个value值。
来来来,上代码:
public class OptionalTest {
public static void main(String[] args) {
Optional<String> optional = Optional.of("hello");
// optional = Optional.empty();
// 判断optional里面的那个值是否存在,存在的话就直接打印出来
// 编译器是建议调用Optional的get()方法获取容器里面值对象的时候,一定要先调用isPresent()方法进行判断这个值是否存在。如果不这么用而直接调用get()方法的话编译器会发出警告。
// 如果编译器不包含这个对象的话,不判断直接调用get()方法会抛异常
if (optional.isPresent()) {
System.out.println(optional.get());
}
// 但其实返回来说,上面那种写法和我们日常经常写的null为空判断的写法其实是没多大区别的,其实本质上根本没区别。以上的写法是不被推荐的
// Optional的推荐的使用方式如下:
optional.ifPresent(item -> System.out.println(item));// 推荐的Optional使用方式
// 上面的使用方式里面,在ifPresent首先会检查optional容器里面的value值是否为null,为null的话什么也不做,不为null的话才操作参数里面传进去的动作
System.out.println("==========================");
// 如果optional容器里面的value有值,就打印出来值,如果没有的话就打印出来一个备选的值world
System.out.println(optional.orElse("world"));
System.out.println("==========================");
// 接受的是一个Supplier的函数式接口(不接收参数,返回一个值),如果容器里面的值为空的话就要用supplier这个函数式接口获取到一个值打出来,不为空的话就打印容器里面的那个值
System.out.println(optional.orElseGet(() -> "nihao"));
System.out.println("==========================");
// 具体什么时候使用ofNullable,什么时候使用of,视实际情况而定,如果比如你调用第三方拿到的一个数据,这个数据可能为空也可能不为空,那就用ofNullable。如果有一个数据你百分百确定不为空,那么你就用of就行了
String a = "......";
Optional.ofNullable(a);
Optional.of(a);
}
}
下面是一个lambda使用的比较复杂的示例,务必理解透彻:
public class Employee {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Company {
private String name;
private List<Employee> employee;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employee> getEmployee() {
return employee;
}
public void setEmployee(List<Employee> employee) {
this.employee = employee;
}
}
public class OptionalTest2 {
public static void main(String[] args) {
Employee employee = new Employee();
employee.setName("zhangsan");
Employee employee2 = new Employee();
employee2.setName("lisi");
Company company = new Company();
company.setName("company1");
List<Employee> employees = Arrays.asList(employee, employee2);
company.setEmployee(employees);
// 需求:如果company里面的employee不为空,就返回这个employee列表,如果为空的话就构建一个空的List<Employee>对象回来
Optional<Company> optional = Optional.ofNullable(company);
// map方法把一个值映射成另一个值。一个应用lambda表达式的比较复杂的示例,但是又是经常用到的一种写法。很漂亮的代码
System.out.println(optional.map(theCompany -> theCompany.getEmployee()).orElse(Collections.emptyList()));
}
}
不要把Optional当做方法参数传递,也不要在类里定义Optional的成员变量,这些用法都违背了Optional的初衷,说白了就是说它不是这么用的。它通常只用作返回值来规避NPE的风险。