如何避免java中的许多try-catch块
我对java和try-catch块处理异常的想法非常陌生 这大概就是我的结局,必须有更好的方法:如何避免java中的许多try-catch块,java,exception-handling,Java,Exception Handling,我对java和try-catch块处理异常的想法非常陌生 这大概就是我的结局,必须有更好的方法: try { JSONObject jsonObject = new JSONObject(jsonString); int aCount = jsonObject.getInt("acount"); String devTok = jsonObject.getString("dt"); String qURL = jsonObj
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
以同样的方式嵌入了更多的try-catch块,因此最后只有一块catch块。除此之外,应该如何处理异常,Eclipse一直要求my使用try-catch块或“Add-throws声明”
有时我想捕获某些异常,例如,如果它找不到实体,我想打印类似“未找到实体”的内容,如果JSON字符串无法解析为对象,我想打印类似“无法解析JSON”的内容
(我习惯于objective-c,其中是失败的委托方法,或者该方法返回null,并且您已经传递了指向NSError对象的指针(该对象将被“填充”),是否有地方可以了解try-catch?如果您所做的只是捕获它们并打印堆栈跟踪,而不管异常类型如何,您可以将代码包装在一个大的try/catch块中。要保存许多“捕获”,可以捕获
java.lang.Throwable
,这是所有异常实现的接口。如果没有,您可以捕获您调用的代码抛出的每种类型的检查异常,并专门处理它们
Eclipse一直要求您这样做,因为如果检查的异常未被捕获或声明由调用方抛出,Java代码将不会编译
+在回答中添加此评论(谢谢Paul Tomblin):
在生产质量应用程序中,您将记录跟踪,添加一些逻辑,以正确的方式处理异常,采取替代流程,和/或将其重新包装在另一个异常中并抛出它,等等。这完全取决于您试图解决的特定问题。如果您有一个代码块,其中可能引发多种类型的异常,则可以声明两个单独的catch块:
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
} catch (EntityNotFoundException e) {
e.printStackTrace();
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
//..etc.. as many catch blocks as needed
或者,如果您不关心异常的确切类型,您可以使用onyl-one-catch块捕获异常
(或者Throwable
;我记不清Java中异常的超类是什么)
我现在要说的另一点是,您可能没有最模块化的代码。记住,做一件事很好的代码就是好的模块化代码。如果您发现有许多嵌套的黑色块(无论是try/catch块、If/else块等等),您可能需要检查是否可以将一些代码提取到它自己的方法中。当必须处理许多异常时,这也可能使代码看起来更好 异常处理的思想是,您可以在程序流中有意义地处理错误的地方处理错误。与在C中检查每个函数的返回值不同,在C中,大多数情况下,除了进一步传递错误外,您无法执行任何合理的操作,而是在程序中的合理点安装try/catch块: 基本上,只要有一个点,你就可以对错误做出有意义的反应,然后抓住这个错误,把其他的一切都传下去。这样,只有在从错误中进行合理的恢复时才会调用错误处理 例如,最坏的情况是,如果有任何错误阻止了程序有意义地执行,那么您可能几乎什么也捕捉不到,而只是让操作系统来处理这种情况(好吧,可能是一次尝试/捕捉来生成友好的错误消息)
<强>示例(在C++中,对不起,我不能键入java盲):
在本例中,我们可能尝试处理图像,但由于某些预期的原因(内存不足或无法读取图像)而失败。在这种情况下,我们只是返回而不做任何工作,让程序继续优雅。所有其他错误都会传播到更高的点。最重要的是,我们确实不需要在实际的图像处理功能中始终进行错误检查和响应,只要那里的任何代码抛出两个好的异常中的一个就足够了,不用再担心了寓意:如果到处都有try/catch块,那你就错了。首先,从设计的角度来看,捕获和打印异常不是一件好事。有些地方出了问题,而你的代码一直以同样的方式运行,就好像它是对的一样。这通常是不正确的。所以:也许您的方法需要抛出这些异常,而不是捕获它们。也许只有调用者能够决定如果这样的事情失败会发生什么 但除此之外,我能提供的唯一建议是清理代码的语法外观,告诉您可以编写:
try {
...
} catch (...) {
...
} catch (...) {
...
}
您还可以捕获更广泛的异常类,如
exception
,只需编写一个catch块,但这是一个糟糕的设计。在Java7中,您将能够在一个块中捕获多个异常类型 您可以在同一次尝试中捕获多个异常,例如
try{
xyz;
}catch(NullPointerException npx){
npx.getMessage();
}catch(ArrayOutOfBoundsException ax){
ax.getMessage();
}
另外,通过在方法签名中将异常声明为
throws
,您可以将异常传递到堆栈上。如果您有办法从异常中恢复,您应该使用try/catch块,例如,如果您想检查字符串是否为有效整数,您可以编写一个方法(这是一个蹩脚的方法,但只是为了表明这一想法):
如果您没有从异常中恢复的方法,而您所做的只是打印堆栈跟踪,则建议向方法中添加throws声明(如eclipse所建议的),并让调用方处理异常(或将其抛出给调用方)
如果您想处理一些异常并抛出一些其他异常,您也可以这样做。我喜欢将调用放在静态方法后面,只是为了让它更整洁。例如,下面是我的缩减集Json值调用
private static boolean setJsonValue(JSONObject j,String key,Object value)
{
try
{
if(value instanceof Integer)
{
// numbers are special. We want them unquoted.
int valueI = (Integer)value;
j.put(key,valueI);
}
else
j.put(key,value);
return true;
}
catch (JSONException e)
{
// do nothing, it turns out
return false;
}
}
…然后我忽略返回值,因为我不好
某处或
public boolean isInteger(String str) {
try {
new Integer(str);
}
catch(NumberFormatException e) {
return false;
}
return true;
}
private static boolean setJsonValue(JSONObject j,String key,Object value)
{
try
{
if(value instanceof Integer)
{
// numbers are special. We want them unquoted.
int valueI = (Integer)value;
j.put(key,valueI);
}
else
j.put(key,value);
return true;
}
catch (JSONException e)
{
// do nothing, it turns out
return false;
}
}
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
e.printStackTrace();
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
String qURL = null;
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
try {
do smth
try {
do smth more
...
} catch (Exception1 e1) {reaction to e1}
} catch (Exception2 e2) {reaction to e2}
try {
do smth
do smth more
...
}
catch (Exception1 e1) {reaction to e1}
catch (Exception2 e2) {reaction to e2}
try {
do smth
do smth more
...
}
catch (Exception e) {e.printStackTrace();}
try {
do smth
try {
do smth more
...
} catch (Exception1 e1) {reaction to e1}
do smth even if e1 was thrown
} catch (Exception2 e2) {reaction to e2}
private Integer getDatastoreACount() {
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
return (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
// expects an Integer return, so need to deal with this
// but for simplicity I'm just simply recycling 'e'
throw e;
}
}
public void parseJSON(String jsonString) {
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
Integer dsACount = getDatastoreACount();
//etc etc
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
}