try代码块与日志

 

异常分类

有return的情况下try catch finally的执行顺序

    try语句在返回前,将其他所有的操作执行完,保留好要返回的值,而后转入执行finally中的语句,而后分为以下三种情况:

    情况一:如果finally中有return语句,则会将try中的return语句”覆盖“掉,直接执行finally中的return语句,得到返回值,这样便无法得到try之前保留好的返回值。

    情况二:如果finally中没有return语句,也没有改变要返回值,则执行完finally中的语句后,会接着执行try中的return语句,返回之前保留的值。

    情况三:如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况,:

        1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。

        2)如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。

 

try 代码块

       try-catch-finally 是处理程序异常的三部曲。当存在 try 时,可以只有 catch 代码块,也可以只有 finally 代码块,就是不能单独只有 try 这个光杆司令。

       finally 是在 return 表达式运行后执行的。此时return 的结果已经被暂存起来 。finally 代码块执行结束后再将之前暂存的结果返回。

       finally代码块的职责不在于对变量进行赋值等操作,而是清理资源、释放连接、关闭管道流等操作,此时如果有异常也要做 try-catch。

       finally 代码块中使用 return语句,使返回值的判断变得复杂,所以避免返回值不可控,我们不要在 finally 代码块中使用 return 语句。

       分析try代码块与锁的关系,lock 方法可能会抛出 unchecked 异常。如果放在try代码块中,必然触发 finally 中的 unlock 方法执行。对未加锁的对象解锁会抛unchecked 异常Illega!MonitorStateException。 虽然是因为加锁失败而造成程序中断的,但是真正加锁失败的原因可能会被后者覆盖。所以在try代码块之前调用lock()方法,避免由于加锁失败导致 finally 调用 unlock()抛出异常。将lock.lock()移到 try代码块的上方。

Lock lock= new XxxLock();
preDo ();
try {
    //无论加锁是否成功. unlock都会执行,
    lock.lock();//移到try代码块之上
    doSomething();
} finally {
    lock .unlock();
}

 

日志规范

       推荐的日志文件命名方式为 appName_logType logName.log 其中 logType日志类型,推荐分类有 stats 、monitor 、isit等。 logNam 为日志描述。这种命名的好处是通过文件名就可以知道曰志文件属于什么应用,什么类型 ,什么目的,也有利于归类查找。例如: mppserv 应用中单独监控时区转换异常的日志文件名定义为

mppserver _monitor_ timeZoneConvert.log。

       记录曰志时要思考三个问题:①日志是否有人看 ②看到这条日志能做什么 ③能不能提升问题排查效率。

 

日志框架

       日志框架分为三大部分,包括日志门面、曰志适配器、日志库。利用门面设计模式,即 Facade 来进行解耦,使日志使用变得更加简单。

       门面设计模式是面向对象设计模式中的一种。日志框架采用的就是这种模式。类似JDBC的设计理念。它只提供一套接口规范 自身不负责日志功能的实现。目的是让使用者不需要关注底层具体是哪个日志库来负责日志打印及具体的使用细节等。目前用得最为广泛的曰志门 面有两种slf4j和commons-logging。

       日志库具体实现了日志的相关功能。主流的日志库有三个分别是 log4j,log-jdk,logback。最早 Java 要想记录曰志只能通过Syste. out 或者System. error来完成非常不方便。log4j 就是为了解决这一问题而提出的。它是最早诞生的曰志库。接着 JDK也在 1.4版本引入了一个日志库 java. util.logging. Logger简称log-jdk。这样市面上就出现两种功能的实现。开发者在使用时需要关注所使用的日志库的具体细节。 logback 是最晚出现的,它与log4j 出自同一个作者,是log4j的升级版且本身就实现了slf4j的接口。

       如果是新工程,则推荐使用slf4j+logback 模式。因为 logback 自身实现了slf4j的接口,无须额外引人适配器,另外 logback是log4j 的升级版,具备比 log句更多的优点,可通过如下配置进行集成。

       如果是老工程,则需要根据所使用的日志库来确定门面适配器,通常情况下老工程使用的都是 log4j 。因此以 log4j 日志库为例,可通过如下配置进行集成

       如果老代码中直接使用了 log4j日志库提供的接口来打印曰志,则还需要引人曰志库适配器,配置实例如下所示

       至此我们的工程就完成了日志框架的集成,再加上一个日志配置文件(如logback.xml、log4j.xml 等),并在工程启动时加载,然后就可以进行曰志打印了,示例代码如下

       注意 logger 被定义为 static 变量,是因为这个 logger 与当前类绑定 避免每次都new 一个新对象,造成资源浪费,甚至引发 OutOfMernoryError 问题。

       另外,在使用 slf4j+日志库模式时,要防止日志库冲突,一旦发生则可能会出现日志打印功能失效的问题。例如,某个业务的网站页面出现了 500 错误。但开发工程师翻遍整个系统的日志文件都没有发现任何异常曰志。线下模拟调试发现错误发生时有异常对象抛出并被框架捕获,然后执行了曰志打印的相关代码,但实际没有输出到日志文件。经开发工程师深入排查,当前工程代码中配置的曰志库为 log4j 但工程依赖的 一个jar包间接地引入了 logback 日志库,导致打印日志的 Logger 引用实际指向 ch.qos.logback.classic Logger 对象,二者的冲突引发了日志打印失效的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值