我无法决定如何处理应用程序中的异常。
很多情况下,如果我的异常问题来自1)通过远程服务访问数据,或者2)反序列化JSON对象。不幸的是,我不能保证这些任务都能成功(切断网络连接,格式错误的JSON对象,超出我的控制范围)。
因此,如果我确实遇到异常,我只需在函数中捕获它并将FALSE返回给调用者。我的逻辑是,调用者真正关心的是任务是否成功,而不是为什么没有成功。
下面是一些典型方法的示例代码(在JAVA中)
public boolean doSomething(Object p_somthingToDoOn)
{
boolean result = false;
try{
// if dirty object then clean
doactualStuffOnObject(p_jsonObject);
//assume success (no exception thrown)
result = true;
}
catch(Exception Ex)
{
//don't care about exceptions
Ex.printStackTrace();
}
return result;
}我认为这种方法很好,但是我真的很想知道管理异常的最佳实践是什么(我真的应该一直在调用堆栈上抛出一个异常吗?)
在关键问题摘要:
追踪/编辑
感谢您的反馈,在网上找到了一些关于异常管理的优秀来源:
异常管理似乎是根据上下文的不同而变化的事情之一。但最重要的是,在如何管理系统内的异常方面,应该保持一致。
此外,通过过度尝试/捕获或不尊重异常(异常是警告系统,还需要警告什么?)
此外,这也是来自m3rLinEz的一个不错的选择。
我倾向于同意Anders和您的观点,即大多数来电者只关心手术是否成功。
从这一评论中,它提出了一些在处理例外情况时需要考虑的问题:
发布于 2009-01-03 18:49:36
我觉得奇怪的是,您希望捕获异常并将它们转换为错误代码。为什么您认为调用方更喜欢错误代码而不是异常,而后者是Java和C#中的缺省值?
至于你的问题:
发布于 2009-01-03 18:51:46
这取决于应用程序和情况。如果您构建了一个库组件,那么您应该抛出异常,尽管它们应该被包装成与组件的上下文相关。例如,如果您构建了一个Xml数据库,并且假设您正在使用文件系统来存储您的数据,那么您正在使用文件系统权限来保护数据。您不希望出现FileIOAccessDenied异常,因为这会泄漏您的实现。相反,您将包装异常并抛出一个AccessDenied错误。如果将组件分发给第三方,则尤其如此。
如果可以吞下例外的话。这取决于你的系统。如果您的应用程序能够处理失败案例,并且通知用户失败没有好处,那么继续进行,尽管我强烈建议您记录故障。我总是发现调用它是为了帮助解决问题,并发现他们正在吞咽异常(或者替换它,而不是抛出一个新的,而不设置内部异常)。
一般来说,我使用以下规则:
我发现下面的代码是一种气味:
try
{
//do something
}
catch(Exception)
{
throw;
}这样的代码没有用,也不应该包括在内。
发布于 2009-01-03 21:24:44
我想推荐关于这个话题的另一个好消息来源。这是对C#和Java的发明者、Anders和James的采访,主题分别是Java的检查异常。
失败和例外
页面底部也有大量的资源。
我倾向于同意Anders和您的观点,即大多数来电者只关心手术是否成功。
Bill :您提到了与检查异常有关的可伸缩性和版本控制问题。你能澄清一下这两个问题是什么意思吗? Anders :让我们从版本控制开始,因为在那里很容易看到问题。假设我创建了一个方法foo,它声明它抛出异常A、B和C。在foo的第二版中,我想添加一些特性,而现在foo可能会抛出异常D。对我来说,将D添加到该方法的抛出子句是一个巨大的变化,因为该方法的现有调用者几乎肯定不会处理该异常。 在新版本中向抛出子句添加新异常会破坏客户端代码。这就像向接口添加一个方法一样。在发布接口之后,就所有实际目的而言,它都是不可变的,因为它的任何实现都可能具有要添加到下一个版本中的方法。所以你必须创建一个新的界面。同样,如果有异常,则必须创建一个名为foo2的全新方法,该方法将引发更多异常,或者必须在新foo中捕获异常D,并将D转换为A、B或C。 Bill :但是在这种情况下,即使是在一种没有检查异常的语言中,您也不会破坏他们的代码吗?如果foo的新版本要抛出一个新的异常,客户端应该考虑处理,难道他们的代码不是因为他们在编写代码时没有预料到这个异常而中断了吗? Anders Hejlsberg:不,因为在很多情况下,人们都不在乎。他们不会处理这些异常。在它们的消息循环中有一个底层异常处理程序。该处理程序将只会弹出一个对话框,说明出了什么问题并继续。程序员通过编写“尝试无处不在”来保护他们的代码,所以如果出现异常,他们会正确地退出,但实际上他们对处理异常并不感兴趣。 抛出子句(至少它在Java中的实现方式)并不一定强迫您处理异常,但如果不处理它们,则强制您准确地确认哪些异常可能通过。它要求您捕获已声明的异常或将它们放入您自己的抛出子句中。为了满足这一要求,人们会做一些可笑的事情。例如,他们用“抛出异常”来装饰每一种方法。这完全违背了这个特性,而您只是让程序员编写了更多的粘糊糊。这对任何人都没有帮助。
编辑:添加了更多关于转换的详细信息
https://stackoverflow.com/questions/409563
复制相似问题