成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

How to handle Null Pointer Exception(譯)

MRZYD / 2211人閱讀

摘要:我們應(yīng)該考慮使用字符串常量調(diào)用方法來代替使用對象調(diào)用該方法。然而如果我們通過字符串常量來調(diào)用方法,執(zhí)行流程會正常進行檢查方法的參數(shù)在執(zhí)行方法的方法體之前,務(wù)必對方法的參數(shù)進行值檢查。

原文地址
作者 Sotirios-Efstathios (Stathis) Maneas
譯者 smallclover
Thanks for your watching!

java.lang.NullPoinerException – 怎么處理空指針異常

在java中,null是一個特殊的值,它能夠被賦值給對象的引用。表示該對象的值不確定。當一個應(yīng)用試圖使用或者訪問一個引用為null的對象時,一個NullPointerException 會被拋出。以下列舉的幾種情況將會拋出該異常:

通過一個 null 對象調(diào)用 方法

訪問或者修改一個null 對象的字段

獲取null的長度,比如,一個引用值為null的數(shù)組

訪問或修改一個null對象,比如 一個引用值為null的數(shù)組。

拋出 NullPointException

當你試圖同步一個null對象的時候。

NullPointerException是一個RuntimeException,并且javac編譯器將不會強制你使用try-catch代碼塊處理NullPointerException。

為什么我們需要null值?

正如前面所提到的那樣,在java null值是一個特殊的值。Null值經(jīng)常被使用在一些設(shè)計模式中,如Null Object Pattern 和 Singleton Pattern。前者,提供一個對象來代替當該類型的對象缺失的時候;后者確保該類有且僅有一個類的實例被創(chuàng)建。目的是為了提供一個該對象的全局唯一訪問點。

例如,生成一個類的唯一實例的一般方法是:聲明所有的構(gòu)造函數(shù)為私有,然后創(chuàng)建一個公有的方法返回該類的唯一一個實例

TestSingleton.java:

01    import java.util.UUID;
02     
03    class Singleton {
04     
05         private static Singleton single = null;
06         private String ID = null;
07     
08         private Singleton() {
09              /* Make it private, in order to prevent the creation of new instances of
10               * the Singleton class. */
11     
12              ID = UUID.randomUUID().toString(); // Create a random ID.
13         }
14     
15         public static Singleton getInstance() {
16              if (single == null)
17                   single = new Singleton();
18     
19              return single;
20         }
21     
22         public String getID() {
23              return this.ID;
24         }
25    }
26     
27    public class TestSingleton {
28         public static void main(String[] args) {
29              Singleton s = Singleton.getInstance();
30              System.out.println(s.getID());
31         }
32    }

在上面的這個例子中,我們聲明了一個Singleton類的靜態(tài)實例,該靜態(tài)實例在getInstance內(nèi)部執(zhí)行最多一次的初始化。注意,這里使用null值,使得唯一的實例被創(chuàng)建。

怎樣避免NullPointerException

為了避免出現(xiàn)NullPointerException,在你使用該對象之前確保所有的對象被正常的初始化。注意,當你聲明了一個引用變量,你就真的創(chuàng)建了一個指向?qū)ο蟮闹羔?。在你通過這個對象請求方法或者屬性時你必須確保這個指針不是null。

另外,如果該異常被拋出,請靈活的使用堆棧跟蹤中的信息,通過JVM提供的堆棧跟蹤,我們能夠調(diào)試應(yīng)用。查找exception發(fā)生的方法以及位于該方法的多少行,然后判斷指定的那一行中哪一個引用等于null。在剩余的章節(jié),我們將具體的描述一些處理上述異常情況的技術(shù),然而它們也并不能完全消除NullPointerException的問題,所以程序員還是應(yīng)該在編寫應(yīng)用的時候仔細一些。

1. String與字符串常量作比較

在一個應(yīng)用中經(jīng)常會編寫涉及到比較String變量和字符串常量的代碼。這個字符串常量可能是String類型或者是Enum的一個元素。我們應(yīng)該考慮使用字符串常量調(diào)用equals方法來代替使用null對象調(diào)用該方法。例如觀察一下案例:

1    String str = null;
2    if(str.equals("Test")) {
3         /* The code here will not be reached, as an exception will be thrown. */
4    }

上面的代碼片段將會拋出NullPointerException。然而如果我們通過字符串常量來調(diào)用equals方法,執(zhí)行流程會正常進行:

1    String str = null;
2    if("Test".equals(str)) {
3         /* Correct use case. No exception will be thrown. */
4    }

2. 檢查方法的參數(shù)

在執(zhí)行方法的方法體之前,務(wù)必對方法的參數(shù)進行null值檢查。只有在在確保屬性被檢查之后再繼續(xù)執(zhí)行函數(shù)。另外,在傳遞的參數(shù)有錯誤的時候你可以拋出一個IllegalArgumentException通知調(diào)用者。
例如:

1    public static int getLength(String s) {
2         if (s == null)
3              throw new IllegalArgumentException("The argument cannot be null");
4     
5         return s.length();
6    }

3. 使用String.valueOf()方法代替toString()

當你的應(yīng)用代碼需要獲得一個對象的字符串的表示形式,請避免使用這個對象的toString方法,如果你的對象的引用等于null,將會導致NullPointerException被拋出。我們可以考慮使用靜態(tài)的String.valueOf方法,該方法不會拋出任何異常,當函數(shù)的參數(shù)為null時會打印一個“null”字符串。

譯注:這里只是一個建議,具體使用什么方法還是需要對應(yīng)具體的生產(chǎn)環(huán)境

4. 使用三元運算符

三元運算符對于我們避開NullPointerException是非常有用的。該操作符格式如下:

1    boolean expression ? value1 : value2;

首先一個boolean表達式將會被判斷,如果表達式為true,value1的值將會被返回,否則,value2的值會被返回。我們使用三元表達式處理空指針,如下圖所示

1    String message = (str == null) ? "" : str.substring(0, 10);

在str的引用值為null的時候message變量的值為空,否則,如果str指向?qū)嶋H的數(shù)據(jù),message將會獲取它前10個字符。

5. 創(chuàng)建一個返回空的集合的方法來代替null。

一個非常好的技巧就是創(chuàng)建一個能返回空集合的方法來代替null值。你的應(yīng)用代碼能夠迭代這個空集合并且可以使用它的方法和屬性,而不用擔心拋出NullPointerException。例如

Example.java
01    public class Example {
02         private static List numbers = null;
03     
04         public static List getList() {
05              if (numbers == null)
06                   return Collections.emptyList();
07              else
08                   return numbers;
09         }
10    }

6. 使用Apache的StringUtils類

apache的Commons Lang類庫提供操作java.lang ApI的實用工具類,比如提供很多操作字符串的方法的類StringUtils.java,可以處理值為null的字符串。
你能使用諸如 StringUtils.isNotEmpty、StringUtils.IsEmpty和StringUtils.equals方法,為了減少NullPointerException。舉個例子:

1    if (StringUtils.isNotEmpty(str)) {
2         System.out.println(str.toString());
3    }

7. 使用contains(),containsKey(),containsValue()方法

如果你的應(yīng)用使用集合,例如Maps,那你應(yīng)該考慮使用contains(),containsKey(),containsValue()方法,在你確定value存在于map的時候你可以根據(jù)指定的key來獲取值。

1    Map map = …
2    …
3    String key = …
4    String value = map.get(key);
5    System.out.println(value.toString()); // An exception will be thrown, if the value is null.

上面的代碼片段,我們沒有檢查是否這個key存在于map中,所以可能會返回null值,最安全的做法如下述代碼所示:

1    Map map = …
2    …
3    String key = …
4    if(map.containsKey(key)) {
5         String value = map.get(key);
6         System.out.println(value.toString()); // No exception will be thrown.
7    }

8. 檢查外部方法的返回值

使用第三方庫在我們的日常開發(fā)中是十分常見的。當這些libraries包含的方法返回引用的時候,確保方法返回的引用不是null。另外,應(yīng)該認真的閱讀方法的Javadoc,為了更好的理解它的功能以及它的返回值。

9. 使用斷言

當你在測試代碼時使用斷言是十分有用的,為了避免執(zhí)行的代碼片段拋出NullPointerException。Java斷言通過關(guān)鍵字assert來執(zhí)行的并且在斷言出錯時會拋出AssertionError。
注意你必須明確的啟用斷言標志在JVM中,通過執(zhí)行參數(shù)-ea.否則,斷言將會被完全忽略。
下面代碼是一個使用斷言的例子:

1    public static int getLength(String s) {
2         /* Ensure that the String is not null. */
3         assert (s != null);
4     
5         return s.length();
6    }

如果你執(zhí)行以上的代碼片段并且傳遞給getLength方法一個值為null的參數(shù),然后會有如下的錯誤信息被打印出來:

1    Exception in thread "main" java.lang.AssertionError

10. 單元測試

當你在測試代碼的功能性和正確性的時候單元測試是極其有用的。當你的應(yīng)用代碼出現(xiàn)特定的執(zhí)行流程的時候,花一些時間寫一些測試案例來驗證該流程不會拋出NullPointerException。
Existing NullPointerException safe methods

現(xiàn)有的NullPointerException異常安全的方式

1. 訪問一個類的靜態(tài)成員變量或者方法

當你的代碼試圖訪問一個類的靜態(tài)的變量和方法的時候,記事這個對象的引用為null,JVM也不會拋出NullPointerException。這是由于java編譯器會在特別的地方存儲靜態(tài)的變量和字段。因此,靜態(tài)字段和靜態(tài)方法并不會關(guān)聯(lián)到對象,而是與類的名字有關(guān)聯(lián)。

例如,下述代碼不會拋出NullPointerException。

TestStatic.java :

01    class SampleClass {
02     
03         public static void printMessage() {
04              System.out.println("Hello from Java Code Geeks!");
05         }
06    }
07     
08    public class TestStatic {
09         public static void main(String[] args) {
10              SampleClass sc = null;
11              sc.printMessage();
12         }
13    }

注意,盡管SampleClass對象的引用值為null,但是方法還是將被正確的執(zhí)行。然而,當我們提到靜態(tài)方法和靜態(tài)字段時,最好的訪問方式仍然是靜態(tài)的訪問方式(通過類名來訪問),如SampleClass.printMessage().

2. Instanceof 操作

即使對象的引用值為null,instanceof操作也能被使用。Instanceof操作在引用的值為null的時候會返回false并且不會拋出NullPointerException。請思考一下代碼片段:

1    String str = null;
2    if(str instanceof String)
3         System.out.println("It"s an instance of the String class!");
4    else
5         System.out.println("Not an instance of the String class!");

執(zhí)行的結(jié)果不出所料:

1    Not an instance of the String class!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/66078.html

相關(guān)文章

  • 」Maven 集成 JavaFX 8 以及 <fx:root> 問題探討

    摘要:本文探討使用構(gòu)建集成的可執(zhí)行程序的方法,以及根節(jié)點問題。而使用后,可指導類作為根節(jié)點,避免了嵌套的情況。文件設(shè)計如下文件同時指明了根節(jié)點的類型,資源文件對應(yīng)的設(shè)計如下此時可實現(xiàn)開始時,純代碼方式的自定義控件設(shè)計。 「博客搬家」 原地址: 簡書 原發(fā)表時間: 2017-05-22 上一篇文章探討了使用 IntelliJ IDEA 創(chuàng)建 JavaFX 工程,進而開發(fā)了所需應(yīng)用程序。更...

    joywek 評論0 收藏0
  • 淺析Java異常處理機制

    摘要:關(guān)于異常處理的文章已有相當?shù)钠?,本文簡單總結(jié)了的異常處理機制,并結(jié)合代碼分析了一些異常處理的最佳實踐,對異常的性能開銷進行了簡單分析。是程序正常運行中,可以預(yù)料的意外情況,應(yīng)該被捕獲并進行相應(yīng)處理。 關(guān)于異常處理的文章已有相當?shù)钠?,本文簡單總結(jié)了Java的異常處理機制,并結(jié)合代碼分析了一些異常處理的最佳實踐,對異常的性能開銷進行了簡單分析。博客另一篇文章《[譯]Java異常處理的最...

    NSFish 評論0 收藏0
  • PHP運維開發(fā)常見文件操作

    摘要:最近在寫運維開發(fā)時經(jīng)常碰見一些常見的文件的文件操作。將字符串寫入文件中讀取文件字符串文件不存在把文件轉(zhuǎn)為數(shù)組文件不存在從數(shù)據(jù)庫讀取數(shù)據(jù)存入文件數(shù)據(jù)庫操作將數(shù)組寫入文件調(diào)用時只需要把文件包含進來就可以 最近在寫運維開發(fā)時,經(jīng)常碰見一些常見的文件的文件操作。特別在處理高并發(fā)的需求時,需要REDIS DOCUMENT DB同時操作,如果業(yè)務(wù)人員在文件處理上花費太多的時間會降低開發(fā)效率,因此筆...

    leejan97 評論0 收藏0
  • 】Java異常處理策略

    摘要:指示該錯誤是否嚴重,此屬性會在該異常根據(jù)錯誤的上下文遍歷堆棧時進行更新,嚴重性會指示異常捕獲代碼是應(yīng)該停止程序還是該繼續(xù)處理。引發(fā)異常在檢測到錯誤并無法從中恢復(fù)時,異常將向上傳播到調(diào)用堆棧,直到到達處理它的某個塊。 翻譯:瘋狂的技術(shù)宅 原文標題:Exception handling strategy 原文鏈接:http://programmergate.com/exc...本文首發(fā)微信...

    cartoon 評論0 收藏0
  • Android系統(tǒng)--TouchEvent的處理流程

    摘要:的處理流程就是在樹中的傳遞的過程這個過程分為步第一步,在樹中尋找處理的第二步,剩余的在樹傳遞給目標第一步,在樹中尋找處理的遞歸方式完成從頂向下傳遞,找到到的最底層的從底向上,查找可以處理的并記錄從到的路徑其中涉及到以及遞歸的方式調(diào)用的尋找最 TouchEvent的處理流程就是TouchEvent在View樹中的傳遞的過程:這個過程分為2步:第一步,ACTION_DOWN在View樹中尋...

    edgardeng 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<