1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > java之空指针异常处理

java之空指针异常处理

时间:2020-08-11 04:54:34

相关推荐

java之空指针异常处理

空指针是我们 Java 开发人员经常遇到的一个基本异常,这是一个极其普遍但似乎又无法根治的问题。

本文将带你了解什么是空指针,以及如何有效的避免空指针。

什么是空指针?

当一个变量的值为 null 时,在 Java 里面表示一个不存在的空对象,没有实际内容,没有给它分配内存,null 也是对象成员变量的默认值。所以,一个对象如果没有进行初始化操作,这时候,如果你调用这个对象的方法或者变量,就会出现空指针异常。

如示例会发生空指针异常:

Object object = null;String string = object.toString();

上述情况中,空指针它是属于运行时异常 RuntimeException 的子类,它不是捕获型的,在程序运行时随时可能报出来,而且会造成程序中断。

如何避免空指针

下面说几个空指针的几个最常见的案例及解决之道。

1、字符串比较,常量放前面

if(status.equals(SUCCESS)){}

这个时候 status 可能为 null 造成空指针异常,应该把常量放前面,就能避免空指针异常。

if(SUCCESS.equals(status)){}

2、初始化NULL,指定默认值

User user = NULL;String name = NULL;

在对象初始化的时候给它一个默认值或者默认构造实现,如:

User user = new User();String name = StringUtils.EMPTY;

3、返回值为NULL,返回空集合

在返回一个集合的话,默认会是 null,统一规范返回一个空集合。

举个 List 例子,如:

public List getUserList(){List list = userMapper.gerUserList();return list == null ? new ArrayList() : list;}

这样接收方就不用担心空指针异常了,也不会影响业务。

4、断言

断言是用来检查程序的安全性的,在使用之前进行检查条件,如果不符合条件就报异常,符合就继续。

Java 中自带的断言关键字:assert,如:

assert name == null : “名称不能为空”;

Exception in thread “main” java.lang.AssertionError: 名称不正确

不过默认是不启动断言检查的,需要要带上 JVM 参数:-enableassertions 才能生效。

Java 中这个用的很少,建议使用 Spring 中的,更强大,更方便好用。

Spring中的用法:

Assert.notNull(name,“名称不能为空”);

5、Optional

Optional 是 JDK 8 新增的新特性,再也不用 != null 来判断了。

// book 存在则执行打印Optional<Book> optBook = Optional.of(book);optBook.ifPresent(book -> System.out.println(book.getName()));

// book 为NULL,则返回默认值Optional<Book> optBook = Optional.of(book);String bookName = optBook.orElse("Unknown");

// book 为NULL,则返回默认值Optional<Book> optBook = Optional.of(book);String bookName = optBook.orElse("Unknown");

你可以使用 of() 和 ofNullable() 方法创建包含值的 Optional。两个方法的不同之处在于如果你把 null 值作为参数传递进去,of() 方法会抛出 NullPointerException,而 ofNullable() 不会。

// user 对象是空的,则返回了作为默认值的 user2@Testpublic void whenEmptyValue_thenReturnDefault() {User user = null;User user2 = new User("anna@", "1234");User result = Optional.ofNullable(user).orElse(user2);assertEquals(user2.getEmail(), result.getEmail());}

// 存在即返回,无则提供默认值return user.orElse(UNKNOWN_USER); //而不是 return user.isPresent() ? user.get() : null;// 存在即返回, 无则由函数来产生return user.orElseGet(() -> fetchAUserFromDatabase());// 使用mapreturn user.map(u -> u.getOrders()).orElse(Collections.emptyList())// 上面避免了类似 Java 8 之前的做法if(user.isPresent()) {return user.get().getOrders();} else {return Collections.emptyList();}

// filter 如果有值并且满足断言条件返回包含该值的Optional,否则返回空Optional@Testpublic void useJava8() {List<Student> studentList = initData();for (Student student : studentList) {Optional<Student> studentOptional = Optional.of(student);// 如果年龄大于18则返回Student的Optional// 返回Score的Optional// Score为null则返回0Integer score = studentOptional.filter(s -> s.getAge() >= 18).flatMap(Student::getScore).orElse(0);if (score > 80) {System.out.println("入选:" + student.getName());}}}

空值

Collections.emptyList();StringUtils.EMPTY;

Optional 使用介绍

创建:

Optional.empty(): 创建一个空的 Optional 实例

Optional.of(T t):创建一个 Optional 实例,当 t为null时抛出异常

Optional.ofNullable(T t):创建一个 Optional 实例,但当 t为null时不会抛出异常,而是返回一个空的实例

获取:

get():获取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函数生成的异常

过滤:

filter(Predicate p):如果optional不为空,则执行断言函数p,如果p的结果为true,则返回原本的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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。