处理 NullPointerException的情况
一.假如有两个类 User和Address类,关系如下:
有以下代码
user.getAddress().getProvince();
为了避免NPE情况,我们会这些写:
if(user!=null){
Address address = user.getAddress();
if(address!=null){
String province = address.getProvince();
}
}
为了更优雅根据实际情况可以考虑使用Java8 Optional
二.Optional(T value),empty(),of(T value),ofNullable(T value)
//构造函数,private权限,不能有外部调用
Optional(T value)
//以下三个为public权限
//empty()的作用就是返回EMPTY对象
empty()
of(T value)
ofNullable(T value)
1.of(T value)
其源码为
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
- 通过of(T value)函数所构造出的Optional对象,当Value值为空时,依然会报NullPointerException
- 通过of(T value)函数所构造出的Optional对象,当Value值不为空时,能正常构造Optional对象。
2.ofNullable(T value)
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
相比较of(T value)的区别就是,当value值为null时,of(T value)会报NullPointerException异常;ofNullable(T value)不会throw Exception,ofNullable(T value)直接返回一个EMPTY对象。
三.orElse(T other),orElseGet(Supplier<? extends T> other)和orElseThrow(Supplier<? extends X> exceptionSupplier)
@Test
public void test() {
User user = null;
//当user值不为null时,orElse函数依然会执行createUser()方法
user = Optional.ofNullable(user).orElse(createUser());
//而orElseGet函数并不会执行createUser()方法
user = Optional.ofNullable(user).orElseGet(() -> createUser());
//orElseThrow,就是value值为null时,直接抛一个异常出去
Optional.ofNullable(user).orElseThrow(()->new Exception("用户不存在"));
}
public User createUser(){
User user = new User();
user.setName("zhangsan");
return user;
}
四.map(Function<? super T, ? extends U> mapper)和flatMap(Function<? super T, Optional> mapper)
这两个函数做的是转换值的操作
//对于map而言
public class User {
private String name;
public String getName() {
return name;
}
}
String city = Optional.ofNullable(user).map(u-> u.getName()).get();
//对于flatMap
public class User {
private String name;
public Optional<String> getName() {
return Optional.ofNullable(name);
}
}
String city = Optional.ofNullable(user).flatMap(u-> u.getName()).get();
五. isPresent()和ifPresent(Consumer<? super T> consumer)
//isPresent即判断value值是否为空,
//ifPresent就是在value值不为空时,做一些操作
Optional.ofNullable(user).ifPresent(u->{
// TODO: do something
});
六. filter(Predicate<? super T> predicate)
//filter 方法接受一个 Predicate 来对 Optional 中包含的值进行过滤,
//如果包含的值满足条件,那么还是返回这个 Optional;否则返回 Optional.empty。
//如上所示,如果user的name的长度是小于6的,则返回。如果是大于6的,则返回一个EMPTY对象。
Optional<User> user1 = Optional.ofNullable(user).filter(u -> u.getName().length()<6);
七. 实战例子
//以前写法
public String getCity(User user) throws Exception{
if(user!=null){
if(user.getAddress()!=null){
Address address = user.getAddress();
if(address.getCity()!=null){
return address.getCity();
}
}
}
throw new Excpetion("取值错误");
}
//java8写法
public String getCity(User user) throws Exception{
return Optional.ofNullable(user)
.map(u-> u.getAddress())
.map(a->a.getCity())
.orElseThrow(()->new Exception("取指错误"));
}
//以前
if(user!=null){
dosomething(user);
}
//java8 写法
Optional.ofNullable(user)
.ifPresent(u->{
dosomething(u);
});
//以前
public User getUser(User user) throws Exception{
if(user!=null){
String name = user.getName();
if("zhangsan".equals(name)){
return user;
}
}else{
user = new User();
user.setName("zhangsan");
return user;
}
}
//java8
public User getUser(User user) {
return Optional.ofNullable(user)
.filter(u->"zhangsan".equals(u.getName()))
.orElseGet(()-> {
User user1 = new User();
user1.setName("zhangsan");
return user1;
});
}