欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

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

Java 中任何對象都有可能為空,當我們調(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、當數(shù)組是一個空對象時,取它的長度

Person person = null;
//當數(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, 或給出詳細的注釋;

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

equals和equalsIgnoreCase()方法

Object類中的equals 方法在非空對象引用上實現(xiàn)相等關(guān)系,具有對稱性 x.equals(y) 和 y.equals(x) 結(jié)果是一樣的,但當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ù)的返回值進行包裝。這種方式的優(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是說,我們可以在一行代碼中,進行流水式的 map 操作。而 map 方法內(nèi)部會自動進行空校驗:

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

suppiler 函數(shù)自定義增強 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()以及其他的工具方法而不用擔心空指針異常。

//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

斷言

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

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

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

輸出:

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

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

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

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)文章

  • 利用java和sqlserver建立簡易圖書管理系統(tǒng)的完整步驟

    利用java和sqlserver建立簡易圖書管理系統(tǒng)的完整步驟

    圖書館管理系統(tǒng)是圖書館管理工作中不可缺少的部分,它對于圖書館的管理者和使用者都非常重要,下面這篇文章主要給大家介紹了關(guān)于利用java和sqlserver建立簡易圖書管理系統(tǒng)的完整步驟,需要的朋友可以參考下
    2022-06-06
  • SpringBoot使用Mybatis&Mybatis-plus文件映射配置方法

    SpringBoot使用Mybatis&Mybatis-plus文件映射配置方法

    這篇文章主要介紹了SpringBoot使用Mybatis&Mybatis-plus文件映射配置方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-05-05
  • List集合中對數(shù)據(jù)實現(xiàn)多重規(guī)則進行排序的案例

    List集合中對數(shù)據(jù)實現(xiàn)多重規(guī)則進行排序的案例

    今天小編就為大家分享一篇關(guān)于List集合中對數(shù)據(jù)實現(xiàn)多重規(guī)則進行排序的案例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Struts2+Hibernate實現(xiàn)數(shù)據(jù)分頁的方法

    Struts2+Hibernate實現(xiàn)數(shù)據(jù)分頁的方法

    這篇文章主要介紹了Struts2+Hibernate實現(xiàn)數(shù)據(jù)分頁的方法,結(jié)合實例形式分析了Struts2結(jié)合Hibernate實現(xiàn)數(shù)據(jù)分頁的原理,步驟與相關(guān)實現(xiàn)代碼,需要的朋友可以參考下
    2016-03-03
  • 類似微信說話功能的錄音處理代碼分享

    類似微信說話功能的錄音處理代碼分享

    這篇文章主要介紹了類似微信中說話功能的錄音處理代碼,需要大家自己加UI界面,大家參考使用吧
    2014-01-01
  • SpringBoot快速配置數(shù)據(jù)源的方法

    SpringBoot快速配置數(shù)據(jù)源的方法

    這篇文章主要介紹了SpringBoot快速配置數(shù)據(jù)源的方法,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-10-10
  • 使用SQL保留兩位小數(shù)的實現(xiàn)方式

    使用SQL保留兩位小數(shù)的實現(xiàn)方式

    SQL中保留兩位小數(shù)有三種方法:1、使用ROUND()函數(shù)進行四舍五入;2、使用CONVERT()函數(shù)和3、CAST()函數(shù)進行強制類型轉(zhuǎn)換,這兩種方法會截斷多余的位數(shù),ROUND()函數(shù)會保留0位,而CONVERT()和CAST()會刪除多余的0
    2024-11-11
  • 簡單了解java中int和Integer的區(qū)別

    簡單了解java中int和Integer的區(qū)別

    這篇文章主要介紹了簡單了解java中int和Integer的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • 解析Tars-Java客戶端源碼

    解析Tars-Java客戶端源碼

    Tars是基于名字服務(wù)使用Tars協(xié)議的高性能RPC開發(fā)框架,同時配套一體化的服務(wù)治理平臺,幫助個人或者企業(yè)快速的以微服務(wù)的方式構(gòu)建自己穩(wěn)定可靠的分布式應(yīng)用
    2021-06-06
  • Java項目中防止SQL注入的四種方案總結(jié)

    Java項目中防止SQL注入的四種方案總結(jié)

    SQL注入是一種代碼注入技術(shù),通過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務(wù)器執(zhí)行惡意的SQL命令,下面我們就來看看如何在項目中防止SQL注入吧
    2023-10-10

最新評論