Java中防止空指針異常的辦法。本站提示廣大學習愛好者:(Java中防止空指針異常的辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是Java中防止空指針異常的辦法正文
沒人會愛好空指針異常!有甚麼辦法可以免它們嗎?也許吧。。
本文將評論辯論到以下幾種技巧
1.Optional類型(Java 8中新引入的)
2.Objects類(Java 7華夏有的)
Java 8中的Optional類
它是甚麼?
1.Java 8中新引入的類型
2.它是作為某個指定類型的對象的包裝器或許用於那些不存在對象(null)的場景
簡略來講,它是處置空值的一個更好的替換品(正告:乍一看能夠並沒有那末顯著)
根本用法
它是一品種型(一個類)——那末,怎樣能力創立一個這個類型的實例?
應用下它的三個靜態辦法便可以了:
public static Optional<String> stringOptional(String input) {
return Optional.of(input);
}
簡略清楚明了——創立一個包括這個值的Optional包裝器。記住——假如這個值是null的話,它會拋出NPE!
public static Optional<String> stringNullableOptional(String input) {
if (!new Random().nextBoolean()) {
input = null;
}
return Optional.ofNullable(input);
}
我小我以為是要更好一點。如許就不會有NPE的風險了——假如輸出為null的話,會前往一個空的Optional。
public static Optional<String> emptyOptional() {
return Optional.empty();
}
假如你真的就是願望前往一個”空"值的話。“空”值其實不意味著null。
好吧,那若何去花費/應用Optional呢?
public static void consumingOptional() {
Optional<String> wrapped = Optional.of("aString");
if (wrapped.isPresent()) {
System.out.println("Got string - " + wrapped.get());
}
else {
System.out.println("Gotcha !");
}
}
簡略的辦法就是檢討Optional包裝器能否真的有值(應用isPresent辦法)——你會疑惑這和應用if(myObj != null)比擬有甚麼利益。別擔憂,這個我會說明清晰的。
public static void consumingNullableOptional() {
String input = null;
if (new Random().nextBoolean()) {
input = "iCanBeNull";
}
Optional<String> wrapped = Optional.ofNullable(input);
System.out.println(wrapped.orElse("default"));
}
你可使用orElse辦法,如許萬一封裝切實其實實是一個null值的話可以用它來前往一個默許值——它的利益不言而喻。在提掏出真實值的時刻可以免挪用ifPresent辦法如許顯著過剩的方法了。
public static void consumingEmptyOptional() {
String input = null;
if (new Random().nextBoolean()) {
input = "iCanBeNull";
}
Optional<String> wrapped = Optional.ofNullable(input);
System.out.println(wrapped.orElseGet(
() -> {
return "defaultBySupplier";
}
));
}
這個我就有點弄不清晰了。為何有兩個異樣目標的分歧辦法?orElse和orElseGet明明可以重載的(同名但分歧參數)。
豈論若何,這兩個辦法顯著的差別就在於它們的參數——你可以選擇應用lambda表達式而不是Supplier的實例來完成這個(一個函數式接口)
為何應用Optional要比罕見的null檢討強?
1.應用Optional最年夜的利益就是可以更明確地表述你的意圖——前往null值的話會讓花費者覺得困惑(認真的湧現NPE的時刻)這是否是有意前往的,是以還得檢查javadoc來進一步定位。而應用Optional就相當清楚明了了。
2.有了Optional你便可以完全防止NPE了——如上所提,應用Optional.ofNullable,orElse和orElseGet可讓我們闊別NPE。
另外一個救星!
看下這個代碼片斷
package com.abhirockzz.wordpress.npesaviors;
import java.util.Map;
import java.util.Objects;
public class UsingObjects {
String getVal(Map<String, String> aMap, String key) {
return aMap.containsKey(key) ? aMap.get(key) : null;
}
public static void main(String[] args) {
UsingObjects obj = new UsingObjects();
obj.getVal(null, "dummy");
}
}
哪一個能夠會為空?
1.Map對象
2.停止搜刮應用的key
3.辦法挪用的這個實例
假如拋出NPE的話,我們怎樣能肯定究竟是哪一個是null的?
package com.abhirockzz.wordpress.npesaviors;
import java.util.Map;
import java.util.Objects;
public class UsingObjects {
String getValSafe(Map<String, String> aMap, String key) {
Map<String, String> safeMap = Objects.requireNonNull(aMap,
"Map is null");
String safeKey = Objects.requireNonNull(key, "Key is null");
return safeMap.containsKey(safeKey) ? safeMap.get(safeKey) : null;
}
public static void main(String[] args) {
UsingObjects obj = new UsingObjects();
obj.getValSafe(null, "dummy");
}
}
requireNonNull辦法
1.假如對象不為null的話就前往它自己
2.假如值為null的話,前往的NPE會帶有指定的新聞
為何比if(myObj!=null)要好?
你所看到的棧跟蹤信息會很清晰地看見Objects.requireNonNull的辦法挪用。這個再合營你本身的毛病日記,可讓你更快地定位成績。。。至多在我看來是更快。
你還可以本身自義校驗器,好比說完成一個簡略的校驗器來確保沒有空值。
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
public class RandomGist {
public static <T> T requireNonEmpty(T object, Predicate<T> predicate, String msgToCaller){
Objects.requireNonNull(object);
Objects.requireNonNull(predicate);
if (predicate.test(object)){
throw new IllegalArgumentException(msgToCaller);
}
return object;
}
public static void main(String[] args) {
//Usage 1: an empty string (intentional)
String s = "";
System.out.println(requireNonEmpty(Objects.requireNonNull(s), (s1) -> s1.isEmpty() , "My String is Empty!"));
//Usage 2: an empty List (intentional)
List list = Collections.emptyList();
System.out.println(requireNonEmpty(Objects.requireNonNull(list), (l) -> l.isEmpty(), "List is Empty!").size());
//Usage 3: an empty User (intentional)
User user = new User("");
System.out.println(requireNonEmpty(Objects.requireNonNull(user), (u) -> u.getName().isEmpty(), "User is Empty!"));
}
private static class User {
private String name;
public User(String name){
this.name = name;
}
public String getName(){
return name;
}
}
}
不要讓NPE在毛病的處所成為苦楚。我們有很多對象能更好地處置NPE,乃至完全地鏟除它們!