[英]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
由於try catch塊是不必要的,並且不能解決您的原始問題,因此您只需刪除它即可。
使其成為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
。
boolean
指令 在Java中,有兩種異常類型: checked和unchecked 。 已檢查異常是從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;
}
}
上面的示例就是您的情況 ,因為JSONException
從Exception
擴展而來,所以它是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.