Java或C#中异常管理的最佳实践
我坚持决定如何处理我的应用程序中的异常。
很多,如果我的异常问题来自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的漂亮选择评论。
我倾向于同意安德斯海耶斯伯格和你的观点,即如果手术成功或者没有成功,大多数人只会关心。
从这个评论中,它提出了一些在处理异常时需要思考的问题:
对于我来说,想要捕捉异常并将其转换为错误代码似乎很奇怪。 为什么你认为调用者偏好错误代码,而后者在Java和C#中都是默认的?
至于你的问题:
这取决于应用和情况。 如果你构建一个库组件,你应该鼓励异常,虽然它们应该被包装为与你的组件相关的上下文。 例如,如果您构建一个Xml数据库并假设您正在使用文件系统来存储数据,并且您正在使用文件系统权限来保护数据。 你不想冒泡FileIOAccessDenied异常,因为这泄漏了你的实现。 相反,你会包装异常并抛出一个AccessDenied错误。 如果您将组件分发给第三方,则尤其如此。
至于是否可以吞下例外。 这取决于你的系统。 如果您的应用程序可以处理失败案例,并且通知用户失败原因没有任何好处,那么请继续,尽管我强烈建议您记录失败。 我总是发现它被调用来帮助解决问题并发现它们正在吞服异常(或者替换它并抛出一个新的而不设置内部异常)令人沮丧。
一般来说,我使用以下规则:
我发现下面的代码是一种气味:
try
{
//do something
}
catch(Exception)
{
throw;
}
这样的代码没有意义,不应该包括在内。
我想就这个话题推荐另一个好的来源。 本文分别就C#和Java的发明人Anders Hejlsberg和James Gosling就Java的检查异常进行了访谈。
失败和例外
页面底部也有很多资源。
我倾向于同意安德斯海耶斯伯格和你的观点,即如果手术成功或者没有成功,大多数人只会关心。
Bill Venners :您提到了关于检查异常的可伸缩性和版本控制问题。 你能否澄清这两个问题的含义?
Anders Hejlsberg :让我们从版本开始,因为这些问题很容易在那里看到。 假设我创建了一个方法foo,声明它会抛出异常A,B和C.在foo的第二版中,我想添加一些功能,现在foo可能会抛出异常D.这对我来说是一个突破性改变,将D添加到该方法的throws子句中,因为该方法的现有调用者几乎肯定不会处理该异常。
在新版本中为throws子句添加新的异常会破坏客户端代码。 这就像添加一个方法到接口。 在你发布一个接口之后,它的所有实际用途都是不变的,因为它的任何实现都可能有你想要在下一个版本中添加的方法。 所以你必须改为创建一个新的界面。 与异常类似,您可能必须创建一个名为foo2的全新方法来抛出更多异常,否则您必须在新foo中捕获异常D,并将D转换为A,B或C.
比尔·威纳斯 :但是,无论如何,你是不是打破了他们的代码,即使是没有检查异常的语言? 如果新版本的foo将抛出一个客户端应该考虑处理的新异常,那么他们的代码是不是因为他们在编写代码时不希望发生异常而被破坏?
Anders Hejlsberg :不,因为在很多情况下,人们并不在乎。 他们不会处理这些例外情况。 他们的消息循环周围有一个底层异常处理程序。 该处理程序只是提出一个对话框,说明出了什么问题并继续。 程序员通过编写try finally来保护他们的代码,所以如果发生异常,他们会正确地退出,但他们实际上并不想处理异常。
throws子句,至少是它在Java中实现的方式,并不一定会强制你处理异常,但是如果你不处理它们,它会强制你确认哪些异常可能通过。 它要求你要么捕获声明的异常,要么将它们放在你自己的throws子句中。 要解决这个要求,人们会做出荒谬的事情。 例如,他们用“抛出异常”来装饰每个方法。 这完全破坏了这个功能,你只是让程序员写了更多的gobbledy gunk。 这对任何人都没有帮助。
编辑:添加更多关于会话的细节
链接地址: http://www.djcxy.com/p/26611.html