阅读更多

42顶
6踩

编程语言

翻译新闻 改善异常处理的 6 个技巧

2013-01-28 15:48 by 副主编 wangguo 评论(25) 有22567人浏览
在软件开发过程中,往往会出现一些不可预知的错误,这些错误有可能花费你数小时甚至数天的时间。异常处理通常是防止这种未知错误的常用措施,它的好处是你不用再绞尽脑汁去考虑各种错误,这为处理某一类错误提供了一个很有效的方法,使编程效率大大提高。

本文将为你介绍6个技巧,来帮助你提高异常处理的能力。

1.  使用一个单一的、系统范围的异常类

不要针对每种异常类型创建单独的类,而是只创建一个,并使它继承RuntimeException。这可以减少类的数量,并移除你不会去处理的需要声明的异常。

我知道你在想什么:如何告诉异常处理程序,这些是否是同一类型?如何跟踪特定类型的属性?继续读下去。

2.  为错误代码使用枚举

大多数开发者会把导致异常的原因放到消息中,出现异常时,查看日志文件即可。但是这也有一些缺点:

  • 消息不能被翻译
  • 消息不能很容易地映射为易读的文本
  • 无法从程序方面对消息进行检查
由于每个开发者的语言习惯不一样,同样的错误可能有不同的描述形式。


更好的办法是使用枚举来表示异常的类型。针对每种错误创建一个枚举,并使枚举实现一个ErrorCode接口,然后将它引用为异常中的一个字段。

当抛出异常时,只需在适当的枚举中传递即可。

throw new SystemException(PaymentCode.CREDIT_CARD_EXPIRED);

现在,当你需要测试具体情况时,只需比较异常代码即可。

catch (SystemException e) {
  if (e.getErrorCode() == PaymentCode.CREDIT_CARD_EXPIRED) {
  ...
  }
}

在资源包中使用错误代码作为关键字进行检索,即可取回易读的、国际化的文本。

public class SystemExceptionExample3 {
 
    public static void main(String[] args) {
        System.out.println(getUserText(ValidationCode.VALUE_TOO_SHORT));
    }
 
    public static String getUserText(ErrorCode errorCode) {
        if (errorCode == null) {
            return null;
        }
        String key = errorCode.getClass().getSimpleName() + "__" + errorCode;
        ResourceBundle bundle = ResourceBundle.getBundle("com.northconcepts.exception.example.exceptions");
        return bundle.getString(key);
    }
 
}

3.  在枚举类型中添加错误代码

在某些情况下,一个数字形式的错误代码可以对应一个异常,例如HTTP响应。在这种情况下,在ErrorCode接口中添加一个getNumber方法,并在每个枚举类型中实现它。

public enum PaymentCode implements ErrorCode {
  SERVICE_TIMEOUT(101),
  CREDIT_CARD_EXPIRED(102),
  AMOUNT_TOO_HIGH(103),
  INSUFFICIENT_FUNDS(104);
 
  private final int number;
 
  private PaymentCode(int number) {
    this.number = number;
  }
 
  @Override
  public int getNumber() {
    return number;
  }
 
}


这些数字可以是全局唯一的,或者每个枚举类型只对应一个数字。你甚至可以使用隐式ordinal()方法,或者从一个文件/数据库中加载一些数字。

4.  将动态字段添加到异常处理中

好的异常处理也意味着记录相关数据,而不仅仅是堆栈跟踪。这样做会节省你大量用于诊断和重现错误的时间。当你的程序停止工作时,也无需客户告诉你,他们做了什么。

做到这一点最简单的方法是在异常处理中增加一个java.util.Map字段。该字段主要作用是保留所有异常相关的数据。如果你使用fluent interface(连贯接口)模式,你还需要添加一个通用的setter方法。

抛出异常,并带有相关的数据,类似于下面的形式:

throw new SystemException(ValidationCode.VALUE_TOO_SHORT)
  .set("field", field)
  .set("value", value)
  .set("min-length", MIN_LENGTH);

5.  防止不必要的嵌套

长且多余的堆栈跟踪,对谁都没有好处。更糟的是,它们浪费你的时间和资源。当重新抛出异常时,调用一个静态封装方法,而不是异常的构造函数。封装方法将决定何时嵌套异常,以及何时返回原来的实例。

public static SystemException wrap(Throwable exception, ErrorCode errorCode) {
  if (exception instanceof SystemException) {
    SystemException se = (SystemException)exception;
    if (errorCode != null && errorCode != se.getErrorCode()) {
      return new SystemException(exception.getMessage(), exception, errorCode);
    }
    return se;
  } else {
    return new SystemException(exception.getMessage(), exception, errorCode);
  }
}
 
public static SystemException wrap(Throwable exception) {
  return wrap(exception, null);
}

重新抛出异常的代码类似于:

} catch (IOException e) {
  throw SystemException.wrap(e).set("fileName", fileName);
}

6.  使用一个有Web控制面板的中央记录器

根据你的情况,访问产品日志可能会相当麻烦。因为这可能会涉及到多个中间人。

如果你在一个多服务器环境中,事情会更糟。找到出问题的服务器,并确定该问题只影响这一台服务器,这可能相当令人头痛。
我的建议是:

  • 将日志聚合到某一位置,最好是数据库
  • 允许从Web浏览器访问该数据库
有很多方法可以做到这一点,比如:日志收集器、远程记录器、JMX代理、系统监控软件等,你甚至可以自己构建一个。一旦你拥有它,你将能够:

  • 在几秒钟内解决问题。
  • 每个异常都有一个URL对应。
  • 维护人员无需通过其他人的帮助即可确定异常原因
  • 防止测试人员为同样的错误创建多个tickets。
  • 为企业节省资金
  • 节省你的时间,不会影响你的周末度假
异常处理示例下载:NorthConcepts-Exceptions.zip

对此,你有什么好的建议?欢迎评论。

原文:6 Tips to Improve Your Exception Handling
  • 大小: 29.9 KB
42
6
评论 共 25 条 请登录后发表评论
25 楼 gongmingwind 2013-02-08 09:46
不完全赞同
24 楼 gaojiewyh 2013-01-31 00:04
elicer 写道
xumin198908 写道
elicer 写道
1.现在的异常都应该是unchecked exception.
2.另外不要让每个程序员都自己try catch 自己去处理异常, 应该有一个fault barrel.也就是一个central place 来handle异常的处理。让你的程序更清晰。不用到处都是try, catch的肮脏代码。
3.每个异常点都应该有一个唯一的error code,这样当任何异常产生时,你能快速的定位到异常产生点

楼主的见解以是非常不错,这位仁兄的更上一层楼,不知是否也出过这方面的文章或放出示例代码让大家学习学习?
对于刚写程序不久的新手,老是不知道要处理异常,有的人即使catch了异常也不处理,连日志也不打。。


以上一些经验总结是我这么多年工作的经验总结,我最近所做的一个大型的网上银行平台就是采用我上面所讲的原则搭建的异常处理框架。当然fault barrel的实现跟的所采用的框架有很大的关系,比如你如果用的传统的jsp servlet, 你可以用一个简单的filter 作为fault barrier, 在这个filter里面包含根据不同的异常类型做不同的处理。  比如我们的项目用的spring webflow, 我们用的spring webflow 的flow listener 作为fault barrier. 我下面有空会post一篇我们这个网上银行平台的exception handling framework的简介。希望能对大家有所帮助。

期待仁兄赶快介绍,我也在迷惑中
23 楼 zlex 2013-01-30 17:59
http://orangesun.iteye.com/blog/323824

这有篇文章不错。
跟大家分享一下。
22 楼 lvwenwen 2013-01-30 15:21
好,学习了
21 楼 jianshuai 2013-01-30 14:13
elicer 写道
xumin198908 写道
elicer 写道
1.现在的异常都应该是unchecked exception.
2.另外不要让每个程序员都自己try catch 自己去处理异常, 应该有一个fault barrel.也就是一个central place 来handle异常的处理。让你的程序更清晰。不用到处都是try, catch的肮脏代码。
3.每个异常点都应该有一个唯一的error code,这样当任何异常产生时,你能快速的定位到异常产生点

楼主的见解以是非常不错,这位仁兄的更上一层楼,不知是否也出过这方面的文章或放出示例代码让大家学习学习?
对于刚写程序不久的新手,老是不知道要处理异常,有的人即使catch了异常也不处理,连日志也不打。。


以上一些经验总结是我这么多年工作的经验总结,我最近所做的一个大型的网上银行平台就是采用我上面所讲的原则搭建的异常处理框架。当然fault barrel的实现跟的所采用的框架有很大的关系,比如你如果用的传统的jsp servlet, 你可以用一个简单的filter 作为fault barrier, 在这个filter里面包含根据不同的异常类型做不同的处理。  比如我们的项目用的spring webflow, 我们用的spring webflow 的flow listener 作为fault barrier. 我下面有空会post一篇我们这个网上银行平台的exception handling framework的简介。希望能对大家有所帮助。



用handle处理异常的方式确实比本文介绍的好一些。。。代码更清新一些。。希望楼主能share一下。。。
20 楼 xpenxpen 2013-01-30 13:49
很好,受用了
19 楼 finallygo 2013-01-30 13:13
收集日志还是用scribe吧
18 楼 elicer 2013-01-30 00:18
xumin198908 写道
elicer 写道
1.现在的异常都应该是unchecked exception.
2.另外不要让每个程序员都自己try catch 自己去处理异常, 应该有一个fault barrel.也就是一个central place 来handle异常的处理。让你的程序更清晰。不用到处都是try, catch的肮脏代码。
3.每个异常点都应该有一个唯一的error code,这样当任何异常产生时,你能快速的定位到异常产生点

楼主的见解以是非常不错,这位仁兄的更上一层楼,不知是否也出过这方面的文章或放出示例代码让大家学习学习?
对于刚写程序不久的新手,老是不知道要处理异常,有的人即使catch了异常也不处理,连日志也不打。。


以上一些经验总结是我这么多年工作的经验总结,我最近所做的一个大型的网上银行平台就是采用我上面所讲的原则搭建的异常处理框架。当然fault barrel的实现跟的所采用的框架有很大的关系,比如你如果用的传统的jsp servlet, 你可以用一个简单的filter 作为fault barrier, 在这个filter里面包含根据不同的异常类型做不同的处理。  比如我们的项目用的spring webflow, 我们用的spring webflow 的flow listener 作为fault barrier. 我下面有空会post一篇我们这个网上银行平台的exception handling framework的简介。希望能对大家有所帮助。
17 楼 xumin198908 2013-01-29 20:20
elicer 写道
1.现在的异常都应该是unchecked exception.
2.另外不要让每个程序员都自己try catch 自己去处理异常, 应该有一个fault barrel.也就是一个central place 来handle异常的处理。让你的程序更清晰。不用到处都是try, catch的肮脏代码。
3.每个异常点都应该有一个唯一的error code,这样当任何异常产生时,你能快速的定位到异常产生点

楼主的见解以是非常不错,这位仁兄的更上一层楼,不知是否也出过这方面的文章或放出示例代码让大家学习学习?
对于刚写程序不久的新手,老是不知道要处理异常,有的人即使catch了异常也不处理,连日志也不打。。
16 楼 deeplives 2013-01-29 17:29
壹伍叁柒 写道
我还有我身边的人都没有用异常去处理报错程序的习惯。。
在思考。。。



同意, 像ValidationCode.VALUE_TOO_SHORT, 和 PaymentCode.CREDIT_CARD_EXPIRED 这些与业务相关的错误我都不会使用处理异常的方式来做. 不过, 当真的需要自定义异常的时候,文章还是有很好的参考性.
15 楼 程序员之殇 2013-01-29 16:58
将异常放到数据库?这么折腾,对大的服务来说很好,但是耗费的这笔系统资源消耗怎么说?
14 楼 kalman03 2013-01-29 13:31
我猜图是拿powerdesigner画的,异常处理是门技术活,楼主还应说下由此带来的缺点
13 楼 zengjd 2013-01-29 13:15
好东西,不错!
12 楼 java007008 2013-01-29 13:10
什么语言?
11 楼 troyconder 2013-01-29 11:47
英雄所见略同啊
10 楼 grandboy 2013-01-29 11:24
非常实用,还有示例代码可以下载, 非常感谢分享
9 楼 Brera 2013-01-29 10:51
很好的文章,对现在做的事情很有帮助
8 楼 aubdiy 2013-01-29 10:44
好东西,必须留言挺起
7 楼 allwefantasy 2013-01-29 09:59
这篇文章太有用了。很有用的技巧。
6 楼 youarestupid 2013-01-29 09:33
我只想知道图是用什么工具画的?

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 改善异常处理的6个技巧

    在软件开发过程中,往往会出现一些不可预知的错误,这些错误...本文将为你介绍6个技巧,来帮助你提高异常处理的能力。 1. 使用一个单一的、系统范围的异常类 不要针对每种异常类型创建单独的类,而是只创建一个

  • Python异常处理的3个技巧

    如果你用 Python 编程,那么你就无法避开异常,因为异常在这门语言里无处不在。打个比方,当你在脚本执行时按 ctrl+c ...异常处理工作由“捕获”和“抛出”两部分组成。“捕获”指的是使用 try...except 包裹特定语...

  • java 忽略异常_Java异常处理的9个最佳实践

    在 Java 中,异常处理是个很麻烦的事情。初学者觉得它很难理解,甚至是经验丰富的开发者也要花费很长时间决定异常是要处理掉和抛出。所以很多开发团队约定一些原则处理异常。如果你是一个团队的新成员,你可能会很...

  • 编程规范系列:Java 异常处理的 9 个最佳实践

    Java 异常处理的 9 个最佳实践 前言 今天博主将为大家分享Java 异常处理的 9 个最佳实践,不喜勿喷,如有异议欢迎讨论! 有一个强大的地基才能写出健壮的程序! 在 Java 中,异常处理是个很麻烦的事情。初学者觉得...

  • Linux 下 C++ 异常处理技巧

    在 C++中,无论何时在处理程序内捕获一个异常,关于该异常来源的信息都是不为人知的。异常的具体来源可以提供许多更好地处理该异常的重要信息,或者提供一些可以附加到错误日志的信息,以便以后进行分析。 为了解决...

  • 代码审查:提高代码质量的10个技巧

    代码审查可以有效地改善代码质量,保障代码质量,并且减少代码缺陷和代码安全性隐患,促进团队合作,增强软件产品的稳定性和可靠性。作为开发人员,在提交代码前应该经过代码审查。然而,在实际工作中,代码

  • Java 异常处理的 9 个最佳实践

    在 Java 中,异常处理是个很麻烦的事情。初学者觉得它很难理解,甚至是经验丰富的开发者也要花费很长时间决定异常是要处理掉和抛出。 所以很多开发团队约定一些原则处理异常。如果你是一个团队的新成员,你可能会...

  • 异常和错误处理

    为什么使用异常 ... 让代码更加简洁,清洁,更不容错过错误。但是,使用通常的错误码和判断块,有什么不好的,它们的区别是什么?...而且有些事情只有在异常处理的帮助下才能执行,比如说构造函数中检测到的错误;此...

  • 三个好习惯,帮你写好Python里的异常处理!

    如果你用 Python 编程,那么你就无法避开异常,因为异常在这门语言里无处不在。打个比方,当你在脚本执行时按ctrl+c退出,...异常处理工作由“捕获”和“抛出”两部分组成。“捕获”指的是使用try...except包裹特...

  • 【华为云技术分享】9 个Java 异常处理的规则!

    在 Java 中,异常处理是个很麻烦的事情。初学者觉得它很难理解,甚至是经验丰富的开发者也要花费很长时间决定异常是要处理掉和抛出。 所以很多开发团队约定一些原则处理异常。如果你是一个团队的新成员,你可能...

  • 7.Java程序优化-有助于改善性能的编程技巧

    慎用异常 经常使用的try-catch捕获异常对系统性能而言是非常糟糕的。 虽然在一次try-catch中,无法察觉到它对性能带来的损失。但一旦把try-catch放在循环当中,就会给系统性能带来极大的伤害。//try-catch在循环内...

  • 【《重构 改善既有代码的设计》学习笔记1】重构:第一个案例

    【《重构 改善既有代码的设计》学习笔记】重构:第一个案例 本篇文章的内容来自《重构 改善既有代码的设计》一书学习笔记整理笔记并且加上自己的浅显的思考总结! 一、简单的例子 一个影片出租店用的程序,...

  • 机器学习性能改善备忘单:32个帮你做出更好预测模型的技巧和窍门

    作者 | Jason Brownlee 选文 | Aileen 翻译 | 姜范波 校对 | 寒小阳 ...机器学习最有价值(实际应用最广)的部分是预测性建模。...这个备忘单基于本人多年的实践,以及我对顶级机器学习专家和大赛优胜者的

  • 如何在算法比赛中获得出色的表现 :改善模型的5个重要技巧

    以下是我在Kaggle之旅中积累的一些实用技巧。建立自己的模型或只是从一个基线公共内核,并尝试实施这些建议! 回顾过去的比赛 虽然Kaggle的政策是永远不会出现两次相同的比赛,但经常会有非常相似的问题的重新制作。...

  • 构建现代化网站的 20 个技巧

    在过去几年中,我们与web开发者花了很多时间交流,听得最多的一件事情就是创建一个能很好的跨越各种类型浏览器版本与各种设备的网站有多么难。我们为jQuery项目写代码的时候一直有这个问题。因此我们整理了20条编码...

  • More Effective C++35个改善编程与设计的有效方法笔记

    // 错误,不能传递一个const SpecialWidget*变量给一个处理SpecialWidget*类型变量的函数 update(const_cast*>(&csw)); // 正确,csw的const显示地转换掉(csw和sw两个变量值在update函数中能被更新) update(...

  • Effective Modern C++42招独家技巧助你改善C++11和C++14的高效用法笔记

    // 在编译期,编译器会通过expr推导两个型别:一个是T的型别,另一个是ParamType的型别,这两个型别往往不一样 int x = 27; // x的型别是int const int cx = x; // cx的型别是const int const int& rx = x; // ...

  • Linux操作系统相关习题集

    Linux操作系统相关习题集,包含常用名、Linux系统基础知识等

  • 基于java的-30-「计算机毕业设计」基于net的湖南特产销售网站-源码.zip

    提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

Global site tag (gtag.js) - Google Analytics