Java八股文——异常与日志
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
目录
异常与日志
异常捕获是针对非稳定代码的捕获时要区分异常类型并做出相应的处理。
throw
是方法内部抛出具体异常类对象的关键字而throws
则用在方法signature
上表示方法定义者可以通过次方法声明向上抛出异常对象。
异常分类
所有异常都是Throwable
的子类分为Error
和Exception
。
Error
标识系统发生了不可控的错误如StackOverflowError
程序无法处理只能人工介入Exception
checked
需要在代码中显式捕获的异常否则会编译出错包括JDK中定义的ClassNotFoundException
- 无能为力、引起注意型此类异常程序无法处理例如字段超长导致的
SQLException
人工介入 - 力所能及型如发生未授权异常可以跳转至权限页面
- 无能为力、引起注意型此类异常程序无法处理例如字段超长导致的
unchecked
运行时异常都继承自RuntimeException
不需要程序进行显式的捕捉和处理- 可预测异常基于对代码的性能和稳定要求此类不应该抛出如
NullPointerException
- 需捕获异常例如在远程调用时失败需要做相应的处理
- 可透出异常由框架或系统产生的且会自行处理的异常程序无须关心
- 可预测异常基于对代码的性能和稳定要求此类不应该抛出如
try代码块
当存在try的时候可以只有catch或者finally中的一个但是不能两个都没有。
finally中的代码块即使发生Error
也还是会执行用于清理资源、释放连接、关闭管道流等操作。
如果finally没有执行有以下可能
- 没有进入try语句块
- 进入try语句块但是代码运行中出现了死循环或死锁状态
- 进入try语句块但是执行了
System.exit()
操作也就是说如果在执行try语句块的过程中终止了程序此时finally中的语句块还是不会执行
finally语句块注意
-
finally是在return语句块计算完成后在程序返回前执行的。
将return的结果暂存起来待finally代码块执行结束后再将之前暂存的结果返回。
public static int testFinally() { int temp = 100; try { throw new Exception(); } catch (Exception e) { return ++temp; } finally { temp = 0; } }
此时的值是101而不是0。
-
不要在finally语句中使用return会导致返回值变得不可控。
try代码块与锁的关系
lock方法可能抛出unchecked
异常如果放在try中必然触发finally中的unlock
方法执行但是对于未加锁的对象执行unlock
又会有异常所以需要在try之前调用lock()
方法避免由于加锁失败导致finally调用unlock()
抛出异常。
错误代码如下
Lock lock = new Lock();
preHandle();
try {
// 无论加锁是否成功unlock()都会执行
lock.lock();
something();
} finally {
lock.unlock();
}
日志
日志系统应该监控系统运行状况值指对服务器使用状态如内存、CPU等使用情况应用运行情况如响应时间QPS等交互状态应用错误信息。
日志按重要程度递增依次为debug、info、warn、error、fatal(出现的错误会导致程序中断)
对于debug和info级别的日志必须使用条件输出或者占位符的方式打印。原因如果仅是log.debug("id:" + id + symbol);
假设打印级别是info那么此日志不会打印但是还是会执行字符串拼接和toString()
的操作造成了资源浪费。
if(logger.isDebugEnabled) {
log.debug("id:" + id + symbol);
}
logger.debug("id:{} {}", id, symbol);
error级别只记录系统逻辑错误、异常或者违反重要的业务规则。
记录异常时需要输出异常堆栈如果要输出对象实力确保重写了toString()
否则智慧输出对象的hashCode
值。
日志框架
采用门面设计模式由三部分组成
- 日志门面门面设计模式只提供一套接口规范自身不负责日志功能的实现目的是让使用者不需要关注底层具体是哪个日志库来负责日志打印及具体的使用细节等。
slf4j
、commons-logging
。 - 日志库具体实现了日志的相关功能。
log4j
、log-jdk
、logback
。 - 日志适配器
- 日志门面适配器此前的日志库可能没有实现
slf4j
的接口所以可能需要使用slf4j+log4j
的模式 - 日志库适配器老工程用的日志模式未采用门面模式需要适配
- 日志门面适配器此前的日志库可能没有实现
新工程推荐slf4j
+logback
导入依赖+日志配置文件+
private static final Logger logger = LoggerFactory.getLogger(Abc.class);
logger与当前类绑定避免每次new一个对象。