簡體   English   中英

Java:帶有子類的try-catch塊的問題

[英]Java: Issue with try-catch block with child class

我正在用Java(Eclipse Neon)開發Web服務代碼,我有兩個用於數據分配操作的模型類,如下所示。

編輯器強迫我從類'ChatHistoryModel'的構造函數中刪除try catch塊,並顯示以下消息: JSONException無法訪問的catch塊。 永遠不會從try語句主體中拋出此異常

如果刪除了try-catch塊,則在數據分配操作無法分配數據(nil值)時,將導致代碼崩潰。 如果帶有變量is_group_chat的變量拋出空指針異常,則阻止。

如何處理這種情況。

class TestHistoryModel extends TestModel {
    private Boolean is_read, is_group_chat;

    public TestHistoryModel(JSONObject jsonObject){

        super(jsonObject);
        try {

             // value assignment operations

          if (is_group_chat){  // Null pointer exception line

          }

        } catch (JSONException e) {   // Error line
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}



class TestModel {



    public TestModel(JSONObject jsonObject){

        try {

            // value assignment operations

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

這是類的catch塊的錯誤快照-TestHistoryModel

在此處輸入圖片說明

  1. 您將收到“ Unreachable catch block”消息,因為JSONException是一個已檢查的異常,並且聲明try塊中的任何內容都不能引發該JSONException。 因此,永遠不會在您的try塊內拋出此Exception,並且永遠不會使用catch塊。

由於try catch塊是不必要的,並且不能解決您的原始問題,因此您只需刪除它即可。

  1. 之所以得到NullPointerException,是因為您使用的是布爾值對象,而Java對象會嘗試將其自動拆箱為小布爾值。

使其成為NullPointerException安全更改

if (is_group_chat)

if (Boolean.TRUE.equals(is_group_chat))

如果is_group_chat仍然為null,則方法Boolean.TRUE.equals將返回false。

可以刪除嘗試捕獲塊,這確實是解決此問題的錯誤方法。

另一個解決方案是將is_group_chat更改為一個小boolean 但是請記住,這些將使用false初始化為默認值。

1個JSONException

JSONException是一個檢查異常。 這意味着,如果它從未在try語句中拋出,則無法捕獲。 您可以刪除它,因為它不是必需的。 閱讀該JLS Chapiter以獲得更多信息。

2 NullPointerException

像訪問if(is_group_chat)一樣訪問Boolean實例等效於if(is_group_chat.booleanValue()) ,因為它為null,所以得到NullPointerException

  1. 在檢查實例之前檢查實例是否為空
  2. 使用自動裝箱類的boolean指令
  3. 請參閱OH GOD SPIDERS答案以查看替代條件

在Java中,有兩種異常類型: checkedunchecked 已檢查異常是從Exception擴展而來的,而不是從RuntimeException擴展的。 如果某個方法throws {SomeCheckedException}檢查異常,則該方法必須在簽名throws {SomeCheckedException}異常,除非它在方法主體中處理此異常。 我們這樣說: 請格外小心,此方法可能會失敗

這是一個如何處理檢查的異常的示例:

public List<String> getFileLines(Path filePath) throws IOException {
    // this line is throwin checked exception "IOException" therefore, 
    // we need to rethrow this exception since it is not handled by try-catch
    // from this moment, exception handling will be left on "getFileLines" caller
    return readAllLines(filePath, StandardCharsets.UTF_8); 
}

public List<String> getFileLinesOrNull(Path filePath) {
    try {
        // here IOException is caught, so we don't have to rethrow this exception
        return readAllLines(filePath, StandardCharsets.UTF_8);
    } catch (IOException e) {
        return null; // return null if file reading failed...
    }
}

使用方法:

public void getFileLinesTest() {
    try {
        // we are forced to write try-catch since method signature contains "throws IOException"
        List<String> lines = getFileLines(somePath); 
    catch (IOException e) {
        System.out.println("Some error occurred");
    } 
}

public void getFileLinesOrNullTest() {
     List<String> lines = getFileLinesOrNull(somePath); 
     if (lines == null) {
         System.out.println("Something went wrong...");
     }
}

如果我們正在處理已檢查的異常 ,但是沒有行拋出此異常,那么代碼將無法編譯。 編譯器知道方法的簽名中是否有“ throws ...”,因此編譯器可以輕松地識別出這樣的錯誤(因此,我們將這種異常稱為編譯時異常 ):

public List<String> getFileLines() {
    try {
        return Collections.emptyList();
    } catch (IOException e) {  // COMPILATION ERROR! 
        // handling checked exception, but Collections.emptyList(); does not throw IOException 
        // method signature of the Collections.emptyList() is following: 
        // public static List<E> emptyList(); 
        // as you can see there is no "throws IOException"
        return null;
    }
} 

上面的示例就是您的情況 ,因為JSONExceptionException擴展而來,所以它是checked exception ,而在您的代碼中,沒有任何行在try塊中引發此類異常。

但是, TestHistoryModel構造函數將拋出NullPointerException ,該TestHistoryModel 未經檢查,因為它是從RuntimeException擴展而來的。 這些異常在方法簽名中沒有“拋出”異常,因此編譯器不會通過try-catch塊強制我們處理此類異常。 這是一個例子:

public int getLength(String s) {
    if (s == null) {
        // NullPointerException extends from RuntimeException = we are not  forced to write 
        // add "throws NullPointerException " in getLength signature
        throw new NullPointerException();
    }
    return s.length();
}

運行時異常的處理是可選的

public void getLengthTest() {
   int length = getLength(null); // will throw NullPointerException

   try {
       length = getLength(null);
   } catch(NullPointerException e) {
       System.out.println("null argument");
   }
}

注意,我們不必在getLength方法中編寫if (s == null) ,因為如果parameter為null ,並且試圖在null上調用method,則s.length()將自動引發NullPointerException 正是由於if (is_group_chat)這一行,這確實在構造函數中發生。 字段is_group_chat具有Boolean類型。 Boolean 類型引用類型,boolean 類型原始類型 默認情況下,未初始化的“引用類型”變量為null 因此, if (is_group_chat)if (null) ,則拋出NullPointerException

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM