如何去除烦人的空指针异常
前言
平时开发中,我们需要创建对象,往对象中存值和取值,如果传入对象中的书属性值为空,我们直接使用get方法去取值的时候会报NullPointerException这种空指针异常,所有取值前先要判断对象是否为空,通常我们使用if 语句来判断,如下所示:
像这种student类中的属性值太多的话,会写很多的if 语句来判断,代码看起阿来会非常的冗余。可以使用JDK中java.util包下面的Optional类来简化代码,看起来也会非常的优雅。
Optional类中方法介绍
创建Optional类的方法
- Optional.empty(): 创建一个空的 Optional 实例
- Optional.of(T t):创建一个 Optional 实例,当 t为null时抛出异常
- Optional.ofNullable(T t):创建一个 Optional 实例,但当 t为null时不会抛出异常,而是返回一个空的实例
获取Optional中对象实例的方法
- get():获取optional实例中的对象,当optional 容器为空时报错
Optional类中判断方法
- isPresent():判断optional是否为空,如果空则返回false,否则返回true
- ifPresent(Consumer c):如果optional不为空,则将optional中的对象传给Comsumer函数
- orElse(T other):如果optional不为空,则返回optional中的对象;如果为null,则返回 other 这个默认值
- orElseGet(Supplier other):如果optional不为空,则返回optional中的对象;如果为null,则使用Supplier函数生成默认值other
- orElseThrow(Supplier exception):如果optional不为空,则返回optional中的对象;如果为null,则抛出Supplier函数生成的异常
Optional类中过滤方法
- filter(Predicate p):如果optional不为空,则执行断言函数p,如果p的结果为true,则返回原本的optional,否则返回空的optional
Optional类中映射方法
- map(Function<T, U> mapper):如果optional不为空,则将optional中的对象 t 映射成另外一个对象 u,并将 u 存放到一个新的optional容器中。
- flatMap(Function< T,Optional<>> mapper):跟上面一样,在optional不为空的情况下,将对象t映射成另外一个optional
区别:map会自动将u放到optional中,而flatMap则需要手动给u创建一个optional
示例代码
先创建一个Person类:
package com.gavin.oop;
public class Person {
String name;
int age;
//无参构造器
//创建对象使用new关键字,本质是调用构造器
//构造器用来初始化值
public Person() {
}
//有参构造器
//一旦定义了有参构造器,无参构造器也要定义
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
再创建一个User类:
package com.gavin.guava;
import com.gavin.oop.Person;
public class User {
private String name;
private int age;
private String sex;
private Person person;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public User(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
创建一个Optional测试类:
判断对象中的属性值是否为空示例:
package com.gavin.guava;
import com.gavin.oop.Person;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
User user = new User("张三", 23, "男");
getUser(user);
}
public static void getUser (User user) {
Integer personAge = Optional.ofNullable(user).map(User :: getPerson).map(Person::getAge).orElse(0);
String userName = Optional.ofNullable(user).map(User::getName).orElse("无姓名");
System.out.println("personAge=" + personAge);
System.out.println("userName=" + userName);
}
}
执行结果:
Person对象中的age属性没有赋值,就返回了orElse()方法中的结果,User对象中的name属性赋值了,就返回了赋予的值
判断List集合是否为空,不为空就输出集合中所有元素的代码:
package com.gavin.guava;
import com.gavin.oop.Person;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
List<String> strList = new ArrayList<>();
strList.add("1");
strList.add("2");
strList.add("3");
getList(strList);
}
public static void getList(List<String> strList) {
Optional.ofNullable(strList).ifPresent(
list -> {
for (String s : list) {
System.out.println(s);
}
}
);
}
}
执行结果:
ifPresent()方法判断传入的List集合是否为空,不为空就执行ifPresent()中的方法。
orElseThrow方法示例代码:
package com.gavin.guava;
import com.gavin.oop.Person;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
User user = new User(null, 23, "男");
getUserException(user);
}
public static void getUserException (User user) {
String userName = Optional.ofNullable(user).map(User::getName).orElseThrow(IllegalArgumentException::new);
System.out.println("userName=" + userName);
}
}
执行结果:
当User对象中name属性的值为空时,就会直接抛出自定义的异常信息
orElseGet方法示例代码:
package com.gavin.guava;
import com.gavin.oop.Person;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
User user = new User(null, 23, "男");
getUserorElseGet(user);
}
public static void getUserorElseGet (User user) {
String userName = Optional.ofNullable(user).map(User::getName).orElseGet(OptionalTest::getUserName);
System.out.println("userName=" + userName);
}
public static String getUserName() {
String name = "无姓名";
return name;
}
}
执行结果:
User对象中name属性的值为空,就会调用orElseGet()中的getUserName()方法
filter示例代码:
package com.gavin.guava;
import com.gavin.oop.Person;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
User user = new User("张三", 23, "男");
getUserFilter(user);
}
public static void getUserFilter (User user) {
Optional<User> result = Optional.ofNullable(user).filter(u -> u.getName() != null && u.getName().contains("张"));
System.out.println("userName=" + result.get().getName());
}
执行结果:
使用filter方法可以过滤出自己想要的数据,非常方便。
总结
以上就是Optional的具体用法,其它的方法自己可以去试一下,合理使用Optional可以使我们的代码看起来更优雅