在寫代碼的過程當中,出現最多的異常可能就是空指針異常了。說白了,空指針異常就是你拿一個不存在的對象,去訪問它的成員屬性或者方法。咱們暫且看下面的代碼: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
對接收便可!