一、异常注意事项

简单整理了下关于异常的规范:

1)      在异常处理模块中应提供精确、易读的错误原因信息。

2)      不要处理能够避免的异常。

3)      一个方法不应该抛出太多类型的异常,最好不超过三个。

4)      不要在try以及finally字段内部使用return语句。

5)      数据库、io操作等涉及资源池泄漏的操作一定要在finally中来释放资源。

6)      将try/catch区段置于循环之外。

7)      不要将异常用于程序流程控制,异常处理效率低于条件分支,且跳转流程难以预测。

8)      在程序中使用异常处理还是使用错误返回码处理,根据是否有利于程序结构来确定,并且异常和错误码不应该混合使用,推荐使用异常。

9)      异常捕获尽量不要直接catch(Exception),应该把异常细分处理。

10)   对于异常应分类处理,不要只捕捉Exception。

11)   对于异常不能忽略,并且应该记入日志。

二、异常优化

2.1、不要忽略checked Exception

  1)      处理异常,进行修复以让程序继续执行。例如在进行数据库查询时,数据库连接断链后重新链接成功。

  2)      在对异常进行分析后发现这里不能处理它,那么重新抛出异常,让调用者处理。异常依次向上抛出,如果所有方法都不能恰当地处理异常,最终会在用户以恰当的方式提示用户,由用户来判断下一步处理措施。例如在进行数据库查询时,断链后重试几次依旧失败的情况。

  3)      将异常转换为其他异常再抛出,这时应该注意不要丢失原始异常信息。这种情况一般用于将底层异常封装为应用层异常。

  4)      不要捕获异常,应在函数定义中使用throws声明将抛出该异常,让调用者去处理该异常。

  5)      因此,当捕获一个checked Exception的时候,必须对异常进行处理;如果认为不必要在这里作处理,就不要捕获该异常,在方法体中声明方法抛出异常,由上层调用者来处理该异常。

2.2、不要捕获unchecked Exception

  有两种checked Exception:

  1)  Error:这种情况属于JVM发生了不可恢复的故障,例如内存溢出,无法处理。

  2)   RuntimeException:这种情况属于错误的编码导致的,出现异常后需要修改代码才能修复,一般来说catch后没有恰当的处理方式,因此不应该捕获。(该规则不适用于守护线程中处理catch runtime exception)

2.3、不要一次捕获所有的异常

  1)      针对try块中抛出的每种Exception,很可能需要不同的处理和恢复措施,而由于这里只有一个catch块,分别处理就不能实现。

  2)      Try块中还可能抛出RuntimeException,代码中捕获了所有抛出的RuntimeException而没有做任何处理,掩盖了编程的错误,会导致程序难以调试。

2.4、使用finally块释放资源

  什么是资源:程序中使用的数量有限的对象,或者只能独占式访问的对象。例如:线程、线程池、数据库连接、ftp连接,因为资源是“有限的“,因此资源使用后必须释放,以避免程序中的资源被耗尽,影响程序运行。某些资源,使用完毕后会自动释放,如线程,某些资源则需要显示释放,如数据库连接。

  Finally关键字保证无论程序使用任何方式离开try块,finally中的语句都会执行。

   因此,当你需要一个地方来执行在任何情况下都必须执行的代码时,就可以将这些代码放入到finally块中。当你的程序中使用了资源,如数据库连接,文件,Ftp连接,线程等,必须将示范给这些资源的代码写入finally块中。

2.5、finally块中不能抛出异常

  JAVA异常处理机制保证无论在任何情况下都先执行finally快的代码,然后再离开整个try,catch,finally块。在try,catch块中向外抛出异常的时候,JAVA虚拟机先转到finally块执行finally中的代码,然后将异常抛出。但如果在finally块中抛出异常,try,catch块的异常就不能抛出,外部捕捉到的异常就是finally块中的异常信息,而try,catch块中发生的真正的异常堆栈信息则丢失了。

2.6、抛出自定义异常时带上原始异常信息

  Try块捕获抛出的异常后,抛出了新的自定义异常需要将原来异常的堆栈信息带上,利于排错。

2.7、不要同时使用异常机制和返回值来进行异常处理

  例如:

  try{

    ......

  }catch(Exception e){

    throw new Exception(msg,e);

    return " ";

   }

  混合使用JAVA异常处理机制和返回值使程序的异常处理部分变得“丑陋不堪”,并难以理解。如果有多种不同的异常情况,就定义多种不同的异常,而不要像上面代码那样综合使用Exception和返回值。

三、日志优化及注意事项

3.1、Log上下文

  在Log中必须尽量带入上下文的信息,对比以下两个Log信息,后者比前者更有作用。

3.2、Error或者Warn级别中碰到Exception的情况尽量log完整的异常信息

  Error和Warn级别是比较严重的情况,意味着系统出错或者危险,我们需要更多的信息来帮助分析原因,这个时候越多的信息越有帮助。包含以下内容:

  1)      你是在做什么事情的时候出错了

  2)      你是在用什么数据做这个事情的时候出错了

  3)      出错的信息是什么

  对比下面三个Log语句,第一个提供了详尽的信息,第二个只提供了部分信息,Exception的Message不一定包含有用的信息,第三个只告诉你出错了,其他的你一无所知:

  1)      Log.error(“获取用户[{}]的用户信息时出错”,username,ex);

  2)      Log.error(“获取用户[{}]的用户信息时出错”,username,ex.getMessage());

  3)     Log.error(“获取用户[{}]的用户信息时出错”);

3.3、基本的Logger编码

  1)      在一个对象中通常只使用一个Logger对象,Logger应该是static final的,只有在少数需要在构造函数中传递logger的情况下才使用private fianl。

  Static final Logger logger = LoggerFactory.getLogger(Main.class);

  2)      输出Exceptions的全部Throwable信息,因为logger.error(msg)和logger.error(msg,e.getMessage())这样的日志输出方法会丢失掉最重要的StackTrace信息。

  Void foo(){

  Try{

      ......

   }catch(Exception e){

  Logger.error(e.getMessage());//错误

  Logger.error(“msg”,e.getMessage());//错误

      Logger.error(“msg”,e);//正确

   }

  }

  3)      对与不是特别重要的异常,不允许记录日志后又抛出异常,因为这样会多次记录日志,只允许记录一次

  Try{

    ......

  }catch(Exception ex){

    Logger.error(errorMessage,ex);

   Throw new UserSercviceException(errorMessage,ex);

  }

  4)      不允许出现System print(包括System.out.println和System.error.println)语句。

  5)      不允许出现e.printStackTrace。

  6)      日志性能的考虑,如果代码为核心代码,执行频率非常高,则输出日志建议增加判断,尤其是低级别的输出<debug、info、warn>。

  7)      有意义的日志

    通常情况下在程序日志里记录一些比较有意义的状态数据:程序启动,退出的时间点:

    程序运行消耗时间;耗时程序的执行进度;重要变量的状态变化。

    除此之外,在公共的日志里规避打印程序的调试或者提示信息。

  说明:大量地输出无效日志,不利于系统性能提升,也不利于快速定位错误点。记录日志请思考:这些日志真的有人看吗?看到这条日志你能做什么?能不能给问题排查带来好处?

java异常及日志注意事项的更多相关文章

  1. 写给大忙人的ELK最新版6.2.4学习笔记-Logstash和Filebeat解析(java异常堆栈下多行日志配置支持)

    接前一篇CentOS 7下最新版(6.2.4)ELK+Filebeat+Log4j日志集成环境搭建完整指南,继续对ELK. logstash官方最新文档https://www.elastic.co/g ...

  2. ELK学习笔记之Logstash和Filebeat解析对java异常堆栈下多行日志配置支持

    0x00 概述 logstash官方最新文档.假设有几十台服务器,每台服务器要监控系统日志syslog.tomcat日志.nginx日志.mysql日志等等,监控OOM.内存低下进程被kill.ngi ...

  3. Java异常使用要点记录

    近期有离职的想法,奈何简历过于寒碜,技术懂的少,基础也薄弱,想要提升自己却不知从哪里入手.在郁闷一段时间后偶然间看到一篇博客,博主说出了许多人的心声,同时也指出了切入点,的确基础才是重点,是时候沉迷学 ...

  4. java编写规范及注意事项

    java编写规范及注意事项 1.注释 常见注释有三种  //   /**/ /****/ 如何才能写出漂亮的注释呢,注释的目的就是为了使你的代码让人更容易理解和维护,写一手好的注释是一个优秀码农的基本 ...

  5. Java 异常讲解(转)

    六种异常处理的陋习 你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗?   1 OutputStreamWrite ...

  6. 一篇不错的讲解Java异常的文章(转载)

    http://www.blogjava.net/freeman1984/archive/2007/09/27/148850.html 六种异常处理的陋习 你觉得自己是一个Java专家吗?是否肯定自己已 ...

  7. java异常——RuntimeException和User Define Exception

    1.RuntimeException public class RuntimeException { public static void main(String[] args) { // TODO ...

  8. Java异常的面试问题及答案-Part 1

    本文由 ImportNew - 韩远青 翻译自 Journaldev. Java提供了一个健壮的.面向对象的方法来处理出现异常,称为Java异常处理.我以前写过一篇长文章来介绍Java异常处理,今天我 ...

  9. JAVA异常的捕获与抛出原则

    在可能会出现exception的地方,要使用try-catch或者throws或者两者都要.我的判断依据是:如果对可能出现的exception不想被外部(方法的调用者)知道,就在方法内部try-cat ...

随机推荐

  1. bzoj 1564 [NOI2009]二叉查找树(树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1564 [题意] 给定一个Treap,总代价为深度*距离之和.可以每次以K的代价修改权值 ...

  2. javascript中用闭包递归遍历树状数组

    做公司项目时,要求写一个方法,方法的参数为一个菜单数组集合和一个菜单id,菜单数组的格式为树状json,如下面所示: [{"id":28,"text":&quo ...

  3. ntpdate[35450]: the NTP socket is in use, exiting

    当前主机已是NTP服务器,需关闭当前NTP服务,再同步其他NTP服务器的时间 service ntpd stop 然后ps -ef | grep ntp看进程是否已杀掉 然后再次ntpdate Ser ...

  4. Oracle 11G R2 RAC中的scan ip 的用途和基本原理【转】

    Oracle 11G R2 RAC增加了scan ip功能,在11.2之前,client链接数据库的时候要用vip,假如你的cluster有4个节点,那么客户端的tnsnames.ora中就对应有四个 ...

  5. MySQL5.7之多源复制&Nginx中间件(上)【转】

    有生之年系列----MySQL5.7之多源复制&Nginx中间件(上)-wangwenan6-ITPUB博客http://blog.itpub.net/29510932/viewspace-1 ...

  6. 转 Java的 BigDecimal类型比较大小

    这个类是java里精确计算的类 1.比较对象是否相等,一般的对象用equals,但是BigDecimal比较特殊,举个例子 BigDecimal a = new BigDecimal.valueOf( ...

  7. C# 应用程序配置文件App.Config和web.config

    应用程序配置文件,对于asp.net是 web.config,对于WINFORM程序是 App.Config(ExeName.exe.config). 配置文件,对于程序本身来说,就是基础和依据,其本 ...

  8. PHP在引号前面添加反斜杠的原因及PHP去除反斜杠的办法

    昨天用PHP做了个读写html文档的小程序,本地测试正常但是传到网站后发现,提交内容保存的时候会自动在双引号前面增加一个反斜杠“\”,而且每保存一次增加一个反斜杠,很是郁闷. 当然做这个只是为了参加电 ...

  9. cocos2dx中调用TinyXml读取xml配置文件 || cocos2d-x 中跨平台tinyxml读取xml文件方式

    TiXmlDocument *doc = newTiXmlDocument; #if (CC_TARGET_PLATFORM ==CC_PLATFORM_ANDROID) //Android平台tin ...

  10. ArcMap2SLD添加中文支持

    首先,你可以从作者提供的链接下载ArcMap2SLD.zip(支持ArcMap10.2) 1.打开LUT_sld_mapping_file.xml文件(上传文件中已经修改)修改文件<LUT> ...