在写代码的过程当中,出现最多的异常可能就是空指针异常了。说白了,空指针异常就是你拿一个不存在的对象,去访问它的成员属性或者方法。咱们暂且看下面的代码:java
public static String getString() {
return null;
}
public static void main(String[] args) {
// 此处返回null
String str = getString();
System.err.println(str.length());
}
复制代码
很明显,上面程序运行的结果确定是排除烦人的java.lang.NullPointerException
:web
Exception in thread "main" java.lang.NullPointerException
at org.springframework.web.SpringServletContainerInitializer.main(SpringServletContainerInitializer.java:187)
复制代码
可是,其实空指针自己并非那么可怕,可怕的是命名咱们知道有这么一种可能会出现空指针异常,可是咱们殊不知道或者无法提早预判,就像上面的代码片断,在eclipse IDE中是没有任何提示的,以下图:spring
那么有什么办法咱们能够提早预判到可能会抛出NullPointerException
的代码块,而后作防空处理呢!答案是确定的。下面我将介绍几种常见的防空方式,注意,这不是演习,这不是演习,这不是演习。哈哈!bash
Optional
类声明咱们的API下面我将一一举例进行探讨(IDE以eclipse为例):eclipse
前置处理:ui
首先咱们要在eclipse启用基于注解的检查,在Windows->Preference->Java->Compiler->Errors/Warnings->Null Analysis
,以下图所示:编码
JSR 303/305和Spring都提供了相应的的注解,以下所示:spa
@Nonnull
、@Nullable
@NonNull
、@Nullable
在eclipse启动空检验以后,要想使上面的@Nullable
注解生效,还须要将注解的全路径类型配置到上图的Use default annotations for null sercifications
,配置以下图:3d
配置完成以后,再看下面代码:指针
/**
* 表示返回的值可能为空
* @return
*/
@Nullable
public static String getString() {
return null;
}
/**
* 参数不能为空
* @param str
* @return
*/
public static String getName(@NonNull String str) {
return null;
}
public static void main(String[] args) {
// 此处返回null
String str = getString();
System.err.println(str.length());
// 参数为空
getName(null);
}
复制代码
这样子可能为空的代码就一目了然了。固然了,其中的原理仍是IDE支持扫描JSR规范的相关注解,Spring的@NonNull
、@Nullable
也是基于JSR注解实现的,可用于声明方法,字段或者参数。
Java8提供了对null进行建模的类,它叫Optional
。咱们能够把它理解为一个容器,容器里保存的,能够是方法的放回值,也能够是方法参数值,若是方法返回值为null或者参数值为null,那么就返回一个空容器对象。请看下面代码:
/**
* 表示返回的值可能为空
* @return
*/
public static Optional<String> getString() {
// 返回空容器,里边什么也没有
return Optional.empty();
}
/**
* 参数不能为空
* @param str
* @return
*/
public static String getName(Optional<String> str) {
return str.get();
}
public static void main(String[] args) {
// 此处返回Optional.empty()
Optional<String> optional = getString();
// 若是返回的是空容器,那么就返回orElse的值,不然,返回容器里的值
String value = optional.orElse("otherValue");
// 输出otherValue
System.err.println(value);
// 参数为空
getName(Optional.of("value"));
}
复制代码
使用Optional
类很方便对可能返回null的值进行建模,同时Optional
里边提供了不少有用的方法容许咱们传入一个lambda表达式进行处理,很是方便。
Optional
也是能够的Optional
可能会更好一点,由于别人一看就知道,该API方法签名可能会返回空值,使用者只须要用一个Optional
对接收便可!