我正在使用Java(Eclipse Neon)开发Web服务代码,我有两个用于数据分配操作的模型类,如下所示。
编辑器强迫我从类'ChatHistoryModel'的构造函数中删除try catch块,并带有消息: Unreachable catch block for JSONException。从不会从try语句中抛出此异常 体
如果我删除try-catch块,当数据分配操作无法分配数据(nil值)时,将导致代码崩溃。阻止if变量is_group_chat thorws 空指针异常。
如何处理这种情况。
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
答案 0 :(得分:2)
由于try catch块是不必要的,并且无法修复原始问题,您只需将其删除即可。
使其成为NullPointerException安全更改
if (is_group_chat)
到
if (Boolean.TRUE.equals(is_group_chat))
如果is_group_chat
仍然为null,则方法Boolean.TRUE.equals
将返回false。
你的try catch块可以删除,实际上是解决这个问题的错误方法。
另一种解决方案是将is_group_chat
更改为小boolean
。但请记住,这些将使用false
作为默认值进行初始化。
答案 1 :(得分:2)
1 JSONException
JSONException
是一个检查异常。这意味着如果从未在try语句中抛出它,则无法捕获它。您可以根据需要将其删除。请阅读JLS Chapiter以获取更多信息。
2 NullPointerException
像Boolean
一样访问if(is_group_chat)
实例相当于if(is_group_chat.booleanValue())
,因为它为空,您得到NullPointerException
。
boolean
insteand 答案 2 :(得分:2)
在Java中,有两种类型的例外:已选中和未选中。在Exception
未选中时,已检查的例外情况从RuntimeException
延伸。如果某个方法抛出了检查异常,那么该方法必须具有签名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...");
}
}
如果我们正在处理已检查的异常,但没有引发此异常的行,则代码将无法编译。编译器知道方法是否在签名中“抛出...”,因此编译器可以轻松识别这样的错误(因此我们称之为编译时异常这样的例外):
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
延伸,因此已检查异常,而在您的代码中,有没有在try块中抛出此类异常的行。
但是,TestHistoryModel
构造函数正在抛出NullPointerException
未选中,因为它从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");
}
}
注意,我们不必在if (s == null)
方法中编写getLength
,因为s.length()
如果参数为NullPointerException
,则会自动抛出null
我们正试图在null
上调用方法。正是这种情况发生在你的构造函数中,因为这行if (is_group_chat)
。字段is_group_chat
具有Boolean
类型。 Boolean
引用类型与{strong>基本类型 boolean
不同。默认情况下,未初始化的“引用类型”变量为null
。因此if (is_group_chat)
if (null)
正在投掷NullPointerException
。