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

Java中避免空指針的幾種方法解析

 更新時間:2023年12月19日 09:03:15   作者:初念初戀  
這篇文章主要介紹了Java中避免空指針的幾種方法解析,Java 中任何對象都有可能為空,當(dāng)我們調(diào)用空對象的方法時就會拋出 NullPointerException 空指針異常,這是一種非常常見的錯誤類型,需要的朋友可以參考下

前言

Java 編程中哪個異常是你印象最深刻的,那 NullPointerException 空指針可以說是臭名昭著的。不要說初級程序員會碰到,即使是中級,專家級程序員稍不留神,就會掉入這個坑里。

Java 中任何對象都有可能為空,當(dāng)我們調(diào)用空對象的方法時就會拋出 NullPointerException 空指針異常,這是一種非常常見的錯誤類型。我們可以使用若干種方法來避免產(chǎn)生這類異常,使得我們的代碼更為健壯。

空指針出現(xiàn)的幾種情況

1、調(diào)用了空對象的實例方法

public class Person {
    // 屬性
    private String name;
    private int age;
    public void print(){
        System.out.println("This is Person Class");
    }
    public String read(){
        System.out.println("This is person read");
        return null;
    }
    public static void main(String[] args)
    {
        Person person = null;
        //調(diào)用了空對象的實例方法
        person.print();
    }
}

2、訪問了空對象的屬性

Person person = null;
//調(diào)用了空對象的屬性
System.out.println(person.age);

3、當(dāng)數(shù)組是一個空對象時,取它的長度

Person person = null;
//當(dāng)數(shù)組是一個空對象時,取它的長度
System.out.println(person.name.length());

4、方法的返回值是 null, 調(diào)用方直接去使用

Person person = new Person();
//方法的返回值是 null, 調(diào)用方直接去使用
System.out.println(person.read().contains("Java"));

如何從根源避免空指針

1、使用之前一定要初始化,或檢查是否初始化;

2、盡量避免在函數(shù)中返回 NULL, 或給出詳細(xì)的注釋;

3、外部傳值,除非有明細(xì)的說明,否則,一定要判斷是否為 NULL。

equals和equalsIgnoreCase()方法

Object類中的equals 方法在非空對象引用上實現(xiàn)相等關(guān)系,具有對稱性 x.equals(y) 和 y.equals(x) 結(jié)果是一樣的,但當(dāng)x == null時會拋出空指針異常。

例如:

String x = null;
String y = "world";
if(x.equals(y)){ // java.lang.NullPointerException
}
if(y.equals(x)){//即便 x 是 null也能避免 NullPointerException
}

所以我們要把確定不為null的對象或值放在前面。

valueOf()和toString()

調(diào)用null對象的toString()會拋出空指針異常,使用valueOf()可以獲得相同的值,傳遞一個 null 給 valueOf() 將會返回null。尤其是在那些包裝類,像Integer、Float、Double和BigDecimal。

例如:

Integer i = null;
System.out.println(i.toString()); // 拋出NullPointerException異常
System.out.println(String.valueOf(i)); // 返回 null不會出現(xiàn)異常

Optional 類型

Java 8 引入了 Optional 類型,我們可以用它來對函數(shù)的返回值進(jìn)行包裝。這種方式的優(yōu)點是可以明確定義該方法是有可能返回空值的,因此調(diào)用方必須做好相應(yīng)處理,這樣也就不會引發(fā)空指針異常。但是,也不可避免地需要編寫更多代碼,而且會產(chǎn)生很多垃圾對象,增加 GC 的壓力,因此在使用時需要酌情考慮。

在業(yè)務(wù)系統(tǒng)中,對象中嵌套對象是經(jīng)常發(fā)生的場景,如下示例代碼:

// 最外層對象
class Outer {
    Nested nested;
    Nested getNested() {
        return nested;
    }
}
// 第二層對象
class Nested {
    Inner inner;
    Inner getInner() {
        return inner;
    }
}
// 最底層對象
class Inner {
    String foo;
    String getFoo() {
        return foo;
    }
}

業(yè)務(wù)中,假設(shè)我們需要獲取 Outer 對象對底層的 Inner 中的 foo 屬性,我們必須寫一堆的非空校驗,來防止發(fā)生 NullPointerException:

// 繁瑣的代碼
Outer outer = new Outer();
if (outer != null && outer.nested != null && outer.nested.inner != null) {
    System.out.println(outer.nested.inner.foo);
}

在 Java8 中,我們有更優(yōu)雅的解決方式,那就是使用 Optional是說,我們可以在一行代碼中,進(jìn)行流水式的 map 操作。而 map 方法內(nèi)部會自動進(jìn)行空校驗:

Optional.of(new Outer())
    .map(Outer::getNested)
    .map(Nested::getInner)
    .map(Inner::getFoo
    .ifPresent(System.out::println); // 如果不為空,最終輸出 foo 的值

suppiler 函數(shù)自定義增強(qiáng) API

我們可以利用 suppiler 函數(shù)來出一個終極解決方案:

public static <T> Optional<T> resolve(Supplier<T> resolver) {
    try {
        T result = resolver.get();
        return Optional.ofNullable(result);
    }
    catch (NullPointerException e) {
        // 可能會拋出空指針異常,直接返回一個空的 Optional 對象
        return Optional.empty();
    }
}

利用上面的 resolve 方法來重構(gòu)上述的非空校驗代碼段:

Outer obj = new Outer();
// 直接調(diào)用 resolve 方法,內(nèi)部做空指針的處理
resolve(() -> obj.getNested().getInner().getFoo());
    .ifPresent(System.out::println); // 如果不為空,最終輸出 foo 的值

使用null安全的方法和庫

有很多開源庫已經(jīng)為您做了繁重的空指針檢查工作。其中最常用的一個的是Apache commons 中的StringUtils。你可以使用StringUtils.isBlank(),isNumeric(),isWhiteSpace()以及其他的工具方法而不用擔(dān)心空指針異常。

//StringUtils方法是空指針安全的,他們不會拋出空指針異常
System.out.println(StringUtils.isEmpty(null));
System.out.println(StringUtils.isBlank(null));
System.out.println(StringUtils.isNumeric(null));
System.out.println(StringUtils.isAllUpperCase(null));

輸出:
true
true
false
false

斷言

斷言是用來檢查程序的安全性的,在使用之前進(jìn)行檢查條件,如果不符合條件就報異常,符合就繼續(xù)。

Java 中自帶的斷言關(guān)鍵字:assert,如:

assert name == null : "名稱不能為空";

輸出:

Exception in thread "main" java.lang.AssertionError: 名稱不正確

不過默認(rèn)是不啟動斷言檢查的,需要要帶上 JVM 參數(shù):-enableassertions 才能生效。

Java 中這個用的很少,建議使用 Spring 中的,更強(qiáng)大,更方便好用。

Spring中的用法:

Assert.notNull(name,"名稱不能為空");

創(chuàng)建返回空集合而不是null的方法

一個非常好的技術(shù)是創(chuàng)建返回一個空集合的方法,而不是一個null值。你的應(yīng)用程序的代碼可以遍歷空集合并使用它的方法和字段,而不會拋出一個NullPointerException。Collections類提供了方便的空 List,Set 和 Map: Collections.EMPTY_LIST,Collections.EMPTY_SET,Collections.EMPTY_MAP。

例如:

public class Example {
   private static List<Integer> numbers = null;
   public static List<Integer> getList() {
     if (numbers == null){
         return Collections.EMPTY_LIST;
     } else {
         return numbers;
     }
   }
}

賦值時自動拆箱出現(xiàn)空指針

1、變量賦值自動拆箱出現(xiàn)的空指針

Long i = null;
//變量賦值自動拆箱出現(xiàn)的空指針
long j = i;

Long 自動拆箱為 long 實質(zhì)是調(diào)用了 longValue 方法,由于以上的 Long 類型變量值為 null,自動拆箱就會報 NPE。

2、方法傳參時自動拆箱引起空指針異常

public static int add(int x, int y)
{
    return x + y;
}
public static void main(String[] args)
{
    Integer left = null;
    Integer right = null;
    //方法傳參時自動拆箱引起空指針異常
    System.out.println(add(left, right));
}

以上自動拆箱報 NPE,原因在于裝箱的值為 null,調(diào)用 null 的任何 方法都會報錯。

規(guī)避指南:

  • 基本數(shù)據(jù)類型優(yōu)于包裝器類型,優(yōu)先考慮使用基本類型。對于不確定的包裝器類型,一定要校驗是否為 NULL。
  • 基本數(shù)據(jù)類型比包裝器類型更加節(jié)省時間與空間。

小結(jié)

關(guān)于怎么有效避免空指針,其實還有更多,如何避免空指針,一是要注意代碼編寫規(guī)范,二是要提高代碼素養(yǎng)。

到此這篇關(guān)于Java中避免空指針的幾種方法解析的文章就介紹到這了,更多相關(guān)Java避免空指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • windows下使用 intellij idea 編譯 kafka 源碼環(huán)境

    windows下使用 intellij idea 編譯 kafka 源碼環(huán)境

    這篇文章主要介紹了使用 intellij idea 編譯 kafka 源碼的環(huán)境,本文是基于windows下做的項目演示,需要的朋友可以參考下
    2021-10-10
  • 在 Spring Boot 中集成 MinIO 對象存儲

    在 Spring Boot 中集成 MinIO 對象存儲

    MinIO 是一個開源的對象存儲服務(wù)器,專注于高性能、分布式和兼容S3 API的存儲解決方案,本文將介紹如何在 Spring Boot 應(yīng)用程序中集成 MinIO,以便您可以輕松地將對象存儲集成到您的應(yīng)用中,需要的朋友可以參考下
    2023-09-09
  • SpringCloud之分布式配置中心Spring Cloud Config高可用配置實例代碼

    SpringCloud之分布式配置中心Spring Cloud Config高可用配置實例代碼

    這篇文章主要介紹了SpringCloud之分布式配置中心Spring Cloud Config高可用配置實例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • SpringBoot根據(jù)目錄結(jié)構(gòu)自動生成路由前綴的實現(xiàn)代碼

    SpringBoot根據(jù)目錄結(jié)構(gòu)自動生成路由前綴的實現(xiàn)代碼

    本文介紹如何根據(jù)目錄結(jié)構(gòu)給RequestMapping添加路由前綴,具體實現(xiàn)方法,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-08-08
  • java向多線程中傳遞參數(shù)的三種方法詳細(xì)介紹

    java向多線程中傳遞參數(shù)的三種方法詳細(xì)介紹

    但在多線程的異步開發(fā)模式下,數(shù)據(jù)的傳遞和返回和同步開發(fā)模式有很大的區(qū)別。由于線程的運(yùn)行和結(jié)束是不可預(yù)料的,因此,在傳遞和返回數(shù)據(jù)時就無法象函數(shù)一樣通過函數(shù)參數(shù)和return語句來返回數(shù)據(jù)
    2012-11-11
  • Redis緩存策略超詳細(xì)講解

    Redis緩存策略超詳細(xì)講解

    實際開發(fā)中緩存處理是必須的,不可能我們每次客戶端去請求一次服務(wù)器,服務(wù)器每次都要去數(shù)據(jù)庫中進(jìn)行查找,為什么要使用緩存?說到底是為了提高系統(tǒng)的運(yùn)行速度
    2022-09-09
  • 當(dāng)Mybatis遇上目錄樹超全完美解決方案

    當(dāng)Mybatis遇上目錄樹超全完美解決方案

    這篇文章主要介紹了當(dāng)Mybatis遇上目錄樹有哪些解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Java線程中斷interrupt的常用方法

    Java線程中斷interrupt的常用方法

    本文主要介紹了Java線程中斷interrupt的常用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Java序列化常見的三個問題

    Java序列化常見的三個問題

    這篇文章主要介紹了Java序列化常見的三個問題,幫助大家更好的理解和學(xué)習(xí)JAVA,感興趣的朋友可以了解下
    2020-08-08
  • 一文快速了解spring?boot中的@idempotent注解

    一文快速了解spring?boot中的@idempotent注解

    idempotence注解是RESTful API設(shè)計中一個重要的概念,它可以保證操作的可靠性和一致性,下面這篇文章主要給大家介紹了關(guān)于spring?boot中@idempotent注解的相關(guān)資料,需要的朋友可以參考下
    2024-01-01

最新評論

通城县| 阜新市| 仙游县| 灌南县| 合川市| 辽阳县| 承德市| 长治市| 马公市| 泉州市| 琼海市| 库尔勒市| 广饶县| 都江堰市| 清徐县| 荃湾区| 河池市| 重庆市| 陆良县| 安塞县| 堆龙德庆县| 丰台区| 阳泉市| 松潘县| 乐昌市| 双桥区| 乳源| 哈巴河县| 钟祥市| 卢龙县| 巴楚县| 琼海市| 滦南县| 鱼台县| 通河县| 遂宁市| 吕梁市| 汝阳县| 右玉县| 巩义市| 平武县|