程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java中防止空指針異常的辦法

Java中防止空指針異常的辦法

編輯:關於JAVA

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,乃至完全地鏟除它們!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved