`

Java异常那些不得不说的事

    博客分类:
  • Java
阅读更多

一、在finally块中做数据回收操作

比如数据库连接都是很宝贵的,所以最好在finally中关闭连接。

JDBCAgent jdbc = new JDBCAgent();
try{
jdbc.excute("select * from ctp_log");
}catch(SQLException e){
...
}finally{
jdbc.close();
}

 

 

二、不要在异常finally块中定义返回值

如下代码,虽然有很多返回值,但如果真的执行,该代码的返回值永远是3,因为finally是最终执行代码,将其它返回值全部覆盖了!

try{  
  if(x = 1){  
    return throw new RuntimeException();  
  }else{  
    return 1;  
  }  
}catch(Exception e){  
  return 2;  
}finally{  
  return 3;  
} 

 

 

三、覆写Exception的fillInStackTrace方法能提高异常性能

异常性能差是因为fillInStackTrace方法,该方法是带锁的并且需要填充线程异常栈信息。

而我们的业务类异常是不需要记录异常栈的,可以考虑覆写fillInStackTrace方法减小性能开支(据说覆写该方法能提高10倍性能)。

(注:什么是业务类,参照第四点)

public class AccountException extends Exception {
    public Throwable fillInStackTrace() {  
        return this;  
    }
}

 

 

四、业务上的错误使用异常更加OOP

以登录为例,简单的登录方法通过返回boolean即可确认是否登录成功,但如果功能日趋复杂怎么办?通过抛出业务类异常的方式来解析错误信息可读性非常好。

try{
  userManager.login(account,passowrd,identify);
}catch(AccountException e){  
  //账号出错  
}catch(PasswordException e){  
  //密码出错  
}catch(IdentifyException e){
  //验证码错误
}catch(AccountDisableException e){
  //账号被禁用
}

 

 

五、使用正确的log记录异常信息

Log logger = LogFactory.getLog(Demo.class);
try{
  
}catch(SQLException e){
 throw new BusinessException(e);           //√发生该异常会影响后续数据完整性的时候,应该抛出中止操作
 logger.error(e.getLocalizedMessage(),e);  //√记录完整的log日志方便调试
 log.error(e);                             //×这种记录方式只能记录很少的异常信息(连异常发生的位置都没有,记了白记)
 e.printStackTrace();                      //×仅仅将异常打到控制台,开发调试还可以,一旦到生产环境就很难跟踪异常
 System.out.print(e);                      //×同上
}

 

 

六、除了记录异常,记得记录详细参数信息

很多时候通过logger.error(e.getLocalizedMessage(),e)这种记录日志的方式都不一定分析出异常原因。

比如出现一个SQL异常,log日志可能会这样提示:ORA-00936: 缺少表达式。试问这样的错误你能分析这句SQL到底哪儿出了问题吗?不能!所以记录日志的时候最好是把SQL及参数都打印出来,如下例所示。

但记录日志要有分寸,别把客户的机密信息记录出来,如果被发现,我们会负责的!

public List find(Long id,String name){
  String sql = ......;
  try{
  JdbcAgent.excute(sql);
  }catch(Exception e){
  logger.error("sql异常:"+sql+" 参数ID:"+id+",参数name:"+name,e);
  }
}

 

(注:作为研发你可能会说:我通过Eclipse debugger调试就可以知道原因了。但从长远考虑:假如系统已经部署到客户环境上,他们允许你debugger调试吗?不能!所以最好的求助工具就是详细的log日志!)

 

七、从子到父顺序捕获异常

如下所示,假如抛出的是BusinessException异常,那么第二个catch就能捕获到。

如果catch(Exception e)在catch(BusinessException e)之前,则该异常会被catch(Exception e)捕获而不会进catch(BusinessException e)。

try{

}catch(RuntimeException e){

}catch(BusinessException e){//BusinessException extends Exception

}catch(Exception e){

}

 

 

八、使用isInfoEnabled和isDebugEnabled

在看spring和apache等开源体系下的代码时,你会发现在记录log日志时总是看到如下风格的代码:

if (logger.isDebugEnabled()) {
    logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
}
if (logger.isInfoEnabled()) {
	long elapsedTime = System.currentTimeMillis() - startTime;
	logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
}

 

为什么记录debug和info日志前要加个判断?其实原因很简单:提高效率!如上代码所示,在记录日志时进行了字符串拼接,要知道这是会消耗一定资源的。假如当前log日志级别是error,则debug和info是不会被输出的,如果加了if判断则log.debug/info中的字符串拼接就不会执行,自然提高了效率。

在小系统看不出差距,但如果是高并发的系统下,少执行一句代码能明显减小服务器的压力,精细化的代码是有必要的!

 

注意:下面这样的代码是提高不了性能的,因为在if之前就已经准备好log信息:

long elapsedTime = System.currentTimeMillis() - startTime;
String info = "Root WebApplicationContext: initialization completed in " + elapsedTime + " ms";
if (logger.isInfoEnabled()) {
	logger.info(info);
}

 

4
0
分享到:
评论

相关推荐

    Java创建用户异常类

    如果java提供的系统异常类型不能满足程序设计的需求,那么可以设计自己的异常类型。 从java异常类的结构层次可以看出,java类型的公共父类为Throwable.在程序运行中可能出现俩种问题:一种是由硬件系统或JVM导致的...

    Java异常处理终结篇——如何进行Java异常处理设计 - 望远的个人页面 - 开源中国社区1

    摘要使用Java异常的人很多,但能合理使用的却不多,Java异常处理设计是一个冷门的话题,但好的异常设计会让程序有质的变化,所以本文从各个方面分析便总结了,在J

    java异常 各种异常

    java异常 很多人都遇到过 多看看 当自己遇到就能解决了

    保证Java精确异常的指令调度技术

    Java语言的精确异常要求和Java程序...提出的算法可以使指令调度打破Java精确异常要求,能最大程度地发挥作用,并在有效提高代码执行效率的同时确保精确异常要求在异常发生时不被破坏。实验结果证明该算法的有效性和正确性

    Java异常处理

    出现异常不处理,程序会终止,程序终止了,系统不能正常运行。 因为程序的执行过程中总会遇到许多可预知或不可预知的错误事件,例如内存分配、某个目录下本应存在的一个文件找不到、数组越界等等。这些错误事件存在...

    JAVA实验十一 异常处理与集合类

    在实验四和实验五中,在银行类中使用数组存放客户,在客户类中使用数组存放帐号,客户和帐号的数量受到了限制,不能随意增加。修改程序,改用ArrayList来存放客户和帐号,最后测试你的程序。 【Account类代码(填写...

    两数计算+异常处理

    课程作业,实现两数计算及其异常处理,异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。 Java中的异常可以是函数...

    java源码包---java 源码 大量 实例

     Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...

    java求三角形面积(抛出异常)

    自定义三角形类,包含一个构造方法和求面积的方法; 对不能构成三角形的数据将抛出异常;

    JAVA银行取款异常处理程序

    《JAVA程序设计实例教程》第六章异常处理机制的一道课后题。希望支持啊……

    《Java程序设计案例教程》教学课件07异常处理.pptx

    未受检异常在编译阶段不能被Java编译器检测到。不强迫用户利用异常处理机制对未受检异常进行处理。未受检异常的发生是因为程序有逻辑错误。未受检异常首先且主要通过用户在程序编写过程中避免。如果滥用异常处理机制...

    Java开发技术大全(500个源代码).

    notMultipleOfThree.java 把100-200之间不能被3整除的数输出 outputByDoWhile.java 用while循环随机输出数据 outputByWhile.java 用do~while循环随机输出数据 outputMax.java 求两个数中的最大数 ...

    Java面试大全(备战2021) 最新Java面试必问合集 PDF版

    本套Java面试题大全,全的不能再全,需要的朋友可下载试试! 内容 一、Java基础知识面试题 1、Java概述 2、基础语法 3、面向对象 4、IO流? 5、反射 6、网络编程 7、常用API 8、常用工具类库 9、单元测试 10、日志 ...

    java技术学习文档.docx

    Java的变量和方法需要在类中定义,而不能在类外部定义。Java的代码块包括静态代码块、实例代码块和构造代码块,它们会在程序运行时被执行。Java中的异常处理机制可以帮助开发人员避免程序运行时出现的错误。 Java...

    java源码包4

     Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java...

    Java习题(一些不注意就犯的错误)

    Java一些习题 主要是:字符谜题,循环谜题,异常谜题,类谜题,库谜题 附有解决方案

    三角形的判断和异常处理

    请编写Java程序实现该任务,并自定义异常来处理当三个整数不能构成三角形时的情况。(要求:至少处理三种异常,每种异常都要给出异常原因。比如某个数为0,某个数为负数,两数之和不大于第三个数等)

    Java API中的异常类体系框架捕捉及详解.docx

    异常:Exception 主要指编码、环境、用户操作输入出现问题,Exception主要包括两大类:  oRuntimeException:运行时异常,也叫非检查异常...从程序语法角度讲是必须警醒处理的异常,如果不处理,程序就不能编译通过。

    Java多线程之多线程异常捕捉

    在java多线程程序中,所有线程都不允许抛出未捕获的checked exception,也就是说各个线程需要自己把自己的checked exception处理掉,通过此篇文章给大家分享Java多线程之多线程异常捕捉,需要的朋友可以参考下

Global site tag (gtag.js) - Google Analytics