激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java中避免空指針異常的方法

Java中避免空指針異常的方法

2019-12-01 12:56junjie JAVA教程

這篇文章主要介紹了Java中避免空指針異常的方法,本文討論Optional類型、Objects類等技術,需要的朋友可以參考下

沒人會喜歡空指針異常!有什么方法可以避免它們嗎?或許吧。。

本文將討論到以下幾種技術

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,甚至徹底地根除它們!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久久久一区二区三区四区五区 | www.99热视频 | 黄色免费在线电影 | 韩国草草影院 | 精品国产一区二区三区久久久蜜月 | 少妇一级淫片免费放播放 | 日韩毛片网 | 91麻豆精品国产91久久久无需广告 | 国产啊v在线观看 | 色淫影院 | 国内精品久久久久久2021浪潮 | 国产在线观看91一区二区三区 | 27xxoo无遮挡动态视频 | 欧美一级电影网 | 99999久久久久久 | 国产精品爱久久久久久久 | 美女擦逼 | 国产青草视频在线观看 | 免费看a级片 | 日本一区二区精品 | 成人免费一区二区三区视频网站 | 久久精品女人天堂av | 亚洲人片在线观看 | av手机在线免费播放 | 午夜久 | 久章草在线观看 | 久久电影一区二区 | avav在线播放 | 久久在线精品视频 | 亚洲91网 | 欧美成年性h版影视中文字幕 | 亚洲视频在线视频 | 伊人99在线 | 日本一级黄色大片 | 国产一区二区亚洲 | xnxx 日本19| 亚洲精品毛片一区二区三区 | 精品久久久久久久久久久久久久久久久久久 | 26uuu成人人网图片 | 激情综合网俺也去 | 九九热在线视频免费观看 |