Java 8 的Optional对NullPointException的处理
在没用Optional之前我们在获取对象的时候需要大量的类似 if(null!=user)的判断。java8通过Optional对该问题进行优化。
首先我们初始化相关类
- 初始化 User类
import java.util.StringJoiner;
public class User {
/**用户姓名. */
private String name;
/**用户年龄. */
private Integer age;
/**用户地址. */
private Address address;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public User(String name, Integer age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return new StringJoiner(", ", User.class.getSimpleName() + "[", "]")
.add("name='" + name + "'")
.add("age=" + age)
.add("address=" + address)
.toString();
}
}
- 初始化Address类
import java.util.StringJoiner;
public class Address {
/**地址编号. */
private String code;
/**地址名称. */
private String name;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return new StringJoiner(", ", Address.class.getSimpleName() + "[", "]")
.add("code='" + code + "'")
.add("name='" + name + "'")
.toString();
}
}
- 最后演示Optional在各种场景下的应用
import java.util.Optional;
import java.util.function.Supplier;
/**
* 参考:https://mp.weixin.qq.com/s/54fTuplkTbLV1ldsVVUSwg
* <p>
* 总结:代码以简单易懂为主,做到能够平衡
*/
public class Test {
public static User initUser() {
Address address = new Address();
address.setCode("001");
address.setName("大连");
User user = new User();
user.setName("Andy");
user.setAge(30);
user.setAddress(address);
return user;
}
public static void main(String[] args) {
User user = initUser();
//1.如果用户不为空返回对象,否则创建一个对象
User user1 = Optional.ofNullable(user).orElse(new User());
System.out.println("user1:" + user1);//user1:User[name='Andy', age=30, address=Address[code='001', name='大连']]
user = null;
user1 = Optional.ofNullable(user).orElse(new User());
System.out.println("user1:" + user1);//user1:User[name='null', age=null, address=null]
System.out.println("-----------------------------------------------------------------------------------------");
user = initUser();
//2.返回对象的值(如果value不为空则做返回,如果为空则抛出异常 "No value present)
User user2 = Optional.ofNullable(user).get();
System.out.println("user2:" + user2);//user2:User[name='Andy', age=30, address=Address[code='001', name='大连']]
//测试时候打开下面的注释
//user = null;
user2 = Optional.ofNullable(user).get();
System.out.println("user2:" + user2);//Exception in thread "main" java.util.NoSuchElementException: No value present
System.out.println("-----------------------------------------------------------------------------------------");
user = initUser();
//3.判读是否为空(如果对象不为空则为真,如果为空则false)
boolean user3 = Optional.ofNullable(user).isPresent();
System.out.println("user3:" + user3);
user = null;
user3 = Optional.ofNullable(user).isPresent();
System.out.println("user3:" + user3);
System.out.println("-----------------------------------------------------------------------------------------");
user = initUser();
//4.判读是否为空并返回函数(如果对象非空,则运行函数体,如果对象为空,则不执行函数体)
Optional.ofNullable(user).ifPresent(u -> System.out.println("user4:" + u)); //user4:User[name='Andy', age=30, address=Address[code='001', name='大连']]
user = null;
Optional.ofNullable(user).ifPresent(u -> System.out.println("user4:" + u));
System.out.println("-----------------------------------------------------------------------------------------");
user = initUser();
//5.过滤对象(接受一个对象,然后对他进行条件过滤,如果条件符合则返回Optional对象本身,如果不符合则返回空Optional)
Optional<User> user5 = Optional.ofNullable(user).filter(u -> u.getAge() > 10);
System.out.println("user5:" + user5); //Optional[User[name='Andy', age=30, address=Address[code='001', name='大连']]]
System.out.println("user5:" + user5.isPresent());//true
user5 = Optional.ofNullable(user).filter(u -> u.getAge() > 100);
System.out.println("user5:" + user5); //Optional.empty
System.out.println("user5:" + user5.isPresent());//false
user = null;
user5 = Optional.ofNullable(user).filter(u -> u.getAge() > 10);
System.out.println("user5:" + user5);//Optional.empty
System.out.println("user5:" + user5.isPresent());//false
System.out.println("-----------------------------------------------------------------------------------------");
user = initUser();
//6.对象进行二次包装(将对应Function函数式接口中的对象,进行二次运算,封装成新的对象然后返回在Optional中)
String user6 = Optional.ofNullable(user).map(u -> u.getName()).orElse("name为空");
System.out.println("user6:" + user6);//user6:Andy
user = null;
user6 = Optional.ofNullable(user).map(u -> u.getName()).orElse("name为空");
System.out.println("user6:" + user6);//user6:name为空
System.out.println("-----------------------------------------------------------------------------------------");
user = initUser();
//7。Optional对象进行二次包装(将对应Optional< Funcation >函数式接口中的对象,进行二次运算,封装成新的对象然后返回在Optional中)
Optional<String> user7 = Optional.ofNullable(user).map(u -> Optional.ofNullable(u.getName()).orElse("name为空"));
System.out.println("user7:" + user7);//user7:Optional[Andy]
System.out.println("user7:" + user7.get());//user7:Andy
//测试时候打开下面的注释
//user = null;
user7 = Optional.ofNullable(user).map(u -> Optional.ofNullable(u.getName()).orElse("name为空"));
System.out.println("user7:" + user7);//user7:Optional.empty
System.out.println("user7:" + user7.get());//Exception in thread "main" java.util.NoSuchElementException: No value present
System.out.println("-----------------------------------------------------------------------------------------");
user = initUser();
//8.为空返回对象(如果包装对象为空的话,就执行orElse方法里的value,如果非空,则返回写入对象)
User user8 = Optional.ofNullable(user).orElse(new User("小明", 2));
System.out.println("user8:" + user8);//user8:User[name='Andy', age=30, address=Address[code='001', name='大连']]
user = null;
user8 = Optional.ofNullable(user).orElse(new User("小明", 2));
System.out.println("user8:" + user8);//user8:User[name='小明', age=2, address=null]
System.out.println("-----------------------------------------------------------------------------------------");
user = initUser();
//9.为空返回Supplier对象(这个与orElse很相似,入参不一样,入参为Supplier对象,为空返回传入对象的.get()方法,如果非空则返回当前对象)
Optional<Supplier<User>> optionalUserSupplier = Optional.ofNullable(User::new);
//调用get()方法,此时才会调用对象的构造方法,即获得到真正对象
User user9 = Optional.ofNullable(user).orElseGet(optionalUserSupplier.get());
System.out.println("user9:" + user9);//user9:User[name='Andy', age=30, address=Address[code='001', name='大连']]
user = null;
user9 = Optional.ofNullable(user).orElseGet(optionalUserSupplier.get());
System.out.println("user9:" + user9);//user9:User[name='null', age=null, address=null]
System.out.println("-----------------------------------------------------------------------------------------");
user = initUser();
//10.为空返回异常(如果为空,就抛出你定义的异常,如果不为空返回当前对象)
User user10 = Optional.ofNullable(user).orElseThrow(() -> new RuntimeException("没有查询的相关数据"));
System.out.println("user10:" + user10);//user10:User[name='Andy', age=30, address=Address[code='001', name='大连']]
user = null;
user10 = Optional.ofNullable(user).orElseThrow(() -> new RuntimeException("没有查询的相关数据"));
System.out.println("user10:" + user10);//Exception in thread "main" java.lang.RuntimeException: 没有查询的相关数据
}
}