成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

How to handle Null Pointer Exception(譯)

MRZYD / 2227人閱讀

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

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

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

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

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

訪問或者修改一個(gè)null 對(duì)象的字段

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

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

拋出 NullPointException

當(dāng)你試圖同步一個(gè)null對(duì)象的時(shí)候。

NullPointerException是一個(gè)RuntimeException,并且javac編譯器將不會(huì)強(qiáng)制你使用try-catch代碼塊處理NullPointerException。

為什么我們需要null值?

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

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

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    }

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

怎樣避免NullPointerException

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

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

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

在一個(gè)應(yīng)用中經(jīng)常會(huì)編寫涉及到比較String變量和字符串常量的代碼。這個(gè)字符串常量可能是String類型或者是Enum的一個(gè)元素。我們應(yīng)該考慮使用字符串常量調(diào)用equals方法來代替使用null對(duì)象調(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    }

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

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

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

在執(zhí)行方法的方法體之前,務(wù)必對(duì)方法的參數(shù)進(jìn)行null值檢查。只有在在確保屬性被檢查之后再繼續(xù)執(zhí)行函數(shù)。另外,在傳遞的參數(shù)有錯(cuò)誤的時(shí)候你可以拋出一個(gè)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()

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

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

4. 使用三元運(yùn)算符

三元運(yùn)算符對(duì)于我們避開NullPointerException是非常有用的。該操作符格式如下:

1    boolean expression ? value1 : value2;

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

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

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

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

一個(gè)非常好的技巧就是創(chuàng)建一個(gè)能返回空集合的方法來代替null值。你的應(yīng)用代碼能夠迭代這個(gè)空集合并且可以使用它的方法和屬性,而不用擔(dān)心拋出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的實(shí)用工具類,比如提供很多操作字符串的方法的類StringUtils.java,可以處理值為null的字符串。
你能使用諸如 StringUtils.isNotEmpty、StringUtils.IsEmpty和StringUtils.equals方法,為了減少NullPointerException。舉個(gè)例子:

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的時(shí)候你可以根據(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.

上面的代碼片段,我們沒有檢查是否這個(gè)key存在于map中,所以可能會(huì)返回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ā)中是十分常見的。當(dāng)這些libraries包含的方法返回引用的時(shí)候,確保方法返回的引用不是null。另外,應(yīng)該認(rèn)真的閱讀方法的Javadoc,為了更好的理解它的功能以及它的返回值。

9. 使用斷言

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

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方法一個(gè)值為null的參數(shù),然后會(huì)有如下的錯(cuò)誤信息被打印出來:

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

10. 單元測(cè)試

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

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

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

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

例如,下述代碼不會(huì)拋出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對(duì)象的引用值為null,但是方法還是將被正確的執(zhí)行。然而,當(dāng)我們提到靜態(tài)方法和靜態(tài)字段時(shí),最好的訪問方式仍然是靜態(tài)的訪問方式(通過類名來訪問),如SampleClass.printMessage().

2. Instanceof 操作

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

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)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/66078.html

相關(guān)文章

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

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

    joywek 評(píng)論0 收藏0
  • 淺析Java異常處理機(jī)制

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

    NSFish 評(píng)論0 收藏0
  • PHP運(yùn)維開發(fā)常見文件操作

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

    leejan97 評(píng)論0 收藏0
  • 】Java異常處理策略

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

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

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

    edgardeng 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<