最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2014年10月01日 15:02:40   投稿:junjie  
這篇文章主要介紹了Java中避免空指針異常的方法,本文討論Optional類型、Objects類等技術(shù),需要的朋友可以參考下

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

本文將討論到以下幾種技術(shù)

1.Optional類型(Java 8中新引入的)
2.Objects類(Java 7中原有的)

Java 8中的Optional類

它是什么?

1.Java 8中新引入的類型
2.它是作為某個(gè)指定類型的對(duì)象的包裝器或者用于那些不存在對(duì)象(null)的場(chǎng)景

簡(jiǎn)單來(lái)說,它是處理空值的一個(gè)更好的替代品(警告:乍一看可能并沒有那么明顯)

基本用法

它是一種類型(一個(gè)類)——那么,怎么才能創(chuàng)建一個(gè)這個(gè)類型的實(shí)例?

使用下它的三個(gè)靜態(tài)方法就可以了:

復(fù)制代碼 代碼如下:

public static Optional<String> stringOptional(String input) {
    return Optional.of(input);
}

簡(jiǎn)單明了——?jiǎng)?chuàng)建一個(gè)包含這個(gè)值的Optional包裝器。記住——如果這個(gè)值是null的話,它會(huì)拋出NPE!

復(fù)制代碼 代碼如下:

public static Optional<String> stringNullableOptional(String input) {
if (!new Random().nextBoolean()) {
input = null;
}
return Optional.ofNullable(input);
}

我個(gè)人認(rèn)為是要更好一點(diǎn)。這樣就不會(huì)有NPE的風(fēng)險(xiǎn)了——如果輸入為null的話,會(huì)返回一個(gè)空的Optional。

復(fù)制代碼 代碼如下:

public static Optional<String> emptyOptional() {
return Optional.empty();
}

如果你真的就是希望返回一個(gè)”空"值的話?!翱铡敝挡⒉灰馕吨鴑ull。

好吧,那如何去消費(fèi)/使用Optional呢?

復(fù)制代碼 代碼如下:

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 !");
}
}

簡(jiǎn)單的方法就是檢查Optional包裝器是否真的有值(使用isPresent方法)——你會(huì)懷疑這和使用if(myObj != null)相比有什么好處。別擔(dān)心,這個(gè)我會(huì)解釋清楚的。

復(fù)制代碼 代碼如下:

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方法,這樣萬(wàn)一封裝的確實(shí)是一個(gè)null值的話可以用它來(lái)返回一個(gè)默認(rèn)值——它的好處顯而易見。在提取出真實(shí)值的時(shí)候可以避免調(diào)用ifPresent方法這樣明顯多余的方式了。

復(fù)制代碼 代碼如下:

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";
}
 
));
}

這個(gè)我就有點(diǎn)搞不清楚了。為什么有兩個(gè)同樣目的的不同方法?orElse和orElseGet明明可以重載的(同名但不同參數(shù))。

不論如何,這兩個(gè)方法明顯的區(qū)別就在于它們的參數(shù)——你可以選擇使用lambda表達(dá)式而不是Supplier的實(shí)例來(lái)完成這個(gè)(一個(gè)函數(shù)式接口)

為什么使用Optional要比常見的null檢查強(qiáng)?

1.使用Optional最大的好處就是可以更明白地表述你的意圖——返回null值的話會(huì)讓消費(fèi)者感到疑惑(當(dāng)真的出現(xiàn)NPE的時(shí)候)這是不是故意返回的,因此還得查看javadoc來(lái)進(jìn)一步定位。而使用Optional就相當(dāng)明了了。

2.有了Optional你就可以徹底避免NPE了——如上所提,使用Optional.ofNullable,orElse以及orElseGet可以讓我們遠(yuǎn)離NPE。

另一個(gè)救星!

看下這個(gè)代碼片段

復(fù)制代碼 代碼如下:

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");
}
}

哪個(gè)可能會(huì)為空?

1.Map對(duì)象
2.進(jìn)行搜索使用的key
3.方法調(diào)用的這個(gè)實(shí)例

如果拋出NPE的話,我們?cè)趺茨艽_定到底是哪個(gè)是null的?

復(fù)制代碼 代碼如下:

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.如果對(duì)象不為null的話就返回它本身
2.如果值為null的話,返回的NPE會(huì)帶有指定的消息

為什么比if(myObj!=null)要好?

你所看到的棧跟蹤信息會(huì)很清楚地看見Objects.requireNonNull的方法調(diào)用。這個(gè)再配合你自己的錯(cuò)誤日志,可以讓你更快地定位問題。。。至少在我看來(lái)是更快。

你還可以自己自義校驗(yàn)器,比如說實(shí)現(xiàn)一個(gè)簡(jiǎn)單的校驗(yàn)器來(lái)確保沒有空值。

復(fù)制代碼 代碼如下:

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在錯(cuò)誤的地方成為痛苦。我們有許多工具能更好地處理NPE,甚至徹底地根除它們!

相關(guān)文章

  • 深入了解Java核心類庫(kù)--Objects類

    深入了解Java核心類庫(kù)--Objects類

    這篇文章主要介紹了Java中的Object類詳細(xì)介紹,本文講解了Object類的作用、Object類的主要方法、Object類中不能被重寫的方法、Object類的equals方法重寫實(shí)例等內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • java中VO的使用解析

    java中VO的使用解析

    這篇文章主要介紹了java中VO的使用解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring Boot整合MyBatis連接Oracle數(shù)據(jù)庫(kù)的步驟全紀(jì)錄

    Spring Boot整合MyBatis連接Oracle數(shù)據(jù)庫(kù)的步驟全紀(jì)錄

    這篇文章主要給大家介紹了關(guān)于Spring Boot整合MyBatis連接Oracle數(shù)據(jù)庫(kù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • Spring?Security權(quán)限管理小結(jié)

    Spring?Security權(quán)限管理小結(jié)

    SpringSecurity是一個(gè)權(quán)限管理框架,核心是認(rèn)證和授權(quán),前面已經(jīng)系統(tǒng)的給大家介紹過了認(rèn)證的實(shí)現(xiàn)和源碼分析,本文重點(diǎn)來(lái)介紹下權(quán)限管理,需要的朋友可以參考下
    2022-08-08
  • MyBatis-Plus Sequence主鍵的實(shí)現(xiàn)

    MyBatis-Plus Sequence主鍵的實(shí)現(xiàn)

    這篇文章主要介紹了MyBatis-Plus Sequence主鍵的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • spring boot2.0圖片上傳至本地或服務(wù)器并配置虛擬路徑的方法

    spring boot2.0圖片上傳至本地或服務(wù)器并配置虛擬路徑的方法

    最近寫了關(guān)于圖片上傳至本地文件夾或服務(wù)器,上傳路徑到數(shù)據(jù)庫(kù),并在上傳時(shí)預(yù)覽圖片。本文通過實(shí)例代碼給大家分享spring boot2.0圖片上傳至本地或服務(wù)器并配置虛擬路徑的方法,需要的朋友參考下
    2018-12-12
  • 顯示SonarQube私有項(xiàng)目徽章方案流程

    顯示SonarQube私有項(xiàng)目徽章方案流程

    這篇文章主要為大家介紹了如何顯示SonarQube私有項(xiàng)目徽章方案的流程,sonarQube目前不支持私有項(xiàng)目的徽章圖片獲取,這個(gè)問題早在?2018年就在sonar社區(qū)里有過激烈的討論,至今無(wú)果,只能自己尋求一種可以快速實(shí)施的方案
    2022-02-02
  • Retrofit+RxJava實(shí)現(xiàn)帶進(jìn)度下載文件

    Retrofit+RxJava實(shí)現(xiàn)帶進(jìn)度下載文件

    這篇文章主要為大家詳細(xì)介紹了Retrofit+RxJava實(shí)現(xiàn)帶進(jìn)度下載文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Spring?boot集成easy?excel實(shí)現(xiàn)導(dǎo)入導(dǎo)出功能

    Spring?boot集成easy?excel實(shí)現(xiàn)導(dǎo)入導(dǎo)出功能

    這篇文章主要介紹了Spring?boot集成easy?excel實(shí)現(xiàn)導(dǎo)入導(dǎo)出操作,使用easyexcel,首先要引入easyexcel的maven依賴,具體的版本根據(jù)你的需求去設(shè)置,本文結(jié)合實(shí)例代碼講解的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • 解決idea報(bào)錯(cuò) Connot resolve column 的問題

    解決idea報(bào)錯(cuò) Connot resolve column 的問題

    這篇文章主要介紹了解決idea報(bào)錯(cuò) Connot resolve column 的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2021-02-02

最新評(píng)論

延边| 东辽县| 万宁市| 江都市| 沅陵县| 杭锦旗| 禄丰县| 岳阳市| 博乐市| 大化| 高州市| 云龙县| 怀集县| 特克斯县| 措勤县| 梨树县| 阿合奇县| 衡阳县| 邢台市| 萍乡市| 阳高县| 蕉岭县| 拉萨市| 财经| 和政县| 竹北市| 神木县| 宜春市| 商南县| 芦山县| 长宁县| 东乡县| 黄石市| 凤台县| 襄垣县| 连城县| 古田县| 紫阳县| 桓台县| 碌曲县| 白河县|