项目中空指针的烦恼
不管大大小小的项目,只要一个不注意,就会有java.lang.NullPointerException的异常抛出来,自己在测试的时候还好,但是线上项目一旦空指针切没有处理,那就问题大了。所以我们单测的开发好的需求的时候尽量吧所有的场景都测试一下。在 Java 8 之前,任何访问对象方法或属性的调用都可能导致 NullPointerException:,jdk8之后中有Class Optional这个类,能帮助我们更好的解决空指针问题。这个简单而强大的类有助于创建简单、可读性更强、比对应程序错误更少的程序。
api解释如下
可能包含或不包含非空值的容器对象。 如果一个值存在, isPresent()将返回true和get()将返回值。
提供依赖于存在或不存在包含值的其他方法,例如orElse() (如果值不存在则返回默认值)和ifPresent() (如果值存在则执行代码块)。
这是一个value-based课; 使用身份敏感的操作(包括引用相等(的==上的实例),标识哈希码,或同步) Optional可具有不可预测的结果,应当避免。
方法摘要
Modifier and Type |
Method and Description |
static <T> Optional<T> | empty() 返回一个空的 Optional 实例。 |
boolean | equals(Object obj) 指示某个其他对象是否等于此可选项。 |
Optional<T> | filter(Predicate<? super T> predicate) 如果一个值存在,并且该值给定的谓词相匹配时,返回一个 Optional 描述的值,否则返回一个空的 Optional 。 |
<U> Optional<U> | flatMap(Function<? super T,Optional<U>> mapper) 如果一个值存在,应用提供的 Optional 映射函数给它,返回该结果,否则返回一个空的 Optional 。 |
T |
|
int |
|
void | ifPresent(Consumer<? super T> consumer) 如果存在值,则使用该值调用指定的消费者,否则不执行任何操作。 |
boolean | isPresent() 返回 true 如果存在值,否则为 false 。 |
<U>Optional<U> | map(Function<? super T,? extends U> mapper) 如果存在一个值,则应用提供的映射函数,如果结果不为空,则返回一个 Optional 结果的 Optional 。 |
static <T> Optional<T> | of(T value) 返回具有 Optional 的当前非空值的Optional。 |
static <T> Optional<T> | ofNullable(T value) 返回一个 Optional 指定值的Optional,如果非空,则返回一个空的 Optional 。 |
T | orElse(T other) 返回值如果存在,否则返回 other 。 |
T |
|
<X extends Throwable>T | orElseThrow(Supplier<? extends X> exceptionSupplier) 返回包含的值(如果存在),否则抛出由提供的供应商创建的异常。 |
String | toString() 返回此可选的非空字符串表示,适用于调试。 |
常用方法
创建Optional对象的方法: Optional.of(T t):创建一个Optional实例,t必须非空 Optional.empty():创建一个空Optional实例 Optional.ofNullable(T t):创建一个Optional实例,t可以为null 判断Optional对象中是否有对象: boolean isPresent():判断Optional容器中是否有对象 void ifPresent(Consumer<? super T> consumer):如果存在一个值,则应用提供的映射函数,如果结果不为空,则返回一个 Optional结果的 Optional。 获取Optional容器中的对象: T get():如果调用对象包含值,返回该值,否则抛异常 T orElse(T t1):如果调用容器中有值,则返回容器中的值,否则返回t1对象 T orElseGet(Supplier<? extends T> other):如果有值则将其返回,否则返回由Supplier接口实现提供的对象 T orElseThrow(Supplier<? extends X> exceptionSupplier):如果有值则返回,否则抛出由Supplier接口实现提供的异常
项目中可以组合使用的方法
如果项目中的一些参数不确定有值则可以这样使用
示例代码
import java.util.Optional; import java.util.function.Supplier; public class TestOptional { public static void main(String[] args) { UserTest userTest = new UserTest(); userTest.setUserId("1"); //isPresent():判断Optional容器中是否有对象 String userName = userTest.getUserName().isPresent() == true ? userTest.getUserName().get() : "defaultName"; System.out.println(userName); //orElse(T t1) System.out.println(userTest.getUserName().orElse("MrLi")); //orElseGet(Supplier<? extends T> other):如果有值则返回,没值则执行函数 final String s = userTest.getUserName().orElseGet(new Supplier<String>() { @Override public String get() { return userTest.getUserName().orElse("Jhon") + "-test"; } }); System.out.println(s); //orElseThrow:在报错时可抛出异常供我们捕获进行处理 try { userTest.getUserName().orElseThrow(() -> new NullPointerException()); } catch (Throwable throwable) { //do something System.out.println("空指针异常"); } //高级用法:嵌套类中的链式调用 Employee employee = new Employee(); employee.setUser(new Employee.User("MrWan")); String employeeName = Optional.ofNullable(employee) .flatMap(employeeTest -> employeeTest.getUser()) .map(employeeTest -> { employeeTest.setName("MrQing"); return employeeTest; }).get().getName().get(); System.out.println(employeeName); } } class UserTest{ private String userName; private String userId; //get()使用Optional<T>封装一下 public Optional<String> getUserName() { return Optional.ofNullable(userName); } public Optional<String> getUserId() { return Optional.ofNullable(this.userId); } public void setUserName(String userName) { this.userName = userName; } public void setUserId(String userId) { this.userId = userId; } @Override public String toString() { return "UserTest{" + "userName='" + userName + '\'' + ", userId='" + userId + '\'' + '}'; } } class Employee{ private User user; public Optional<User> getUser() { return Optional.ofNullable(user); } public void setUser(User user) { this.user = user; } static class User{ private String name; public User(String name) { this.name = name; } public Optional<String> getName() { return Optional.ofNullable(name); } public void setName(String name) { this.name = name; } } }
运行结果