Java异常与日志处理--JDK Logging、Commoms、Log4j
博主在早期写过一篇Java异常基础知识的博客--传送门,基于之前的基础下,本博客旨在巩固基础知识点,重点介绍更加高级的日志处理!一起来操作吧!
目录
1. Java异常概述
Java异常也是Class,继承关系如下:
- Throwable
- Error
- Exception
RuntimeException
Java的异常体系图如下:
Java异常注意事项
- 必须捕获的异常:
- Exception及其子类,但不包括RuntimeException及其子类
- Exception及其子类称为Checked Exception
- 不需要捕获的异常:
- Error及其子类
- RuntimeException及其子类
- Error是发生了严重的错误(程序对此一般无能为力的):
OutOfMemeryError、NoClassDefFoundError、StackOverflowError...
- Exception是发生了运行时逻辑错误,应该捕获异常并处理:
- 捕获并处理错误:IOException、NumberFormatException...
- 修复程序:NullPointerException、IndexOutOfBoundsException...
声明异常
- 对可能抛出Checked Exception的方法调用:
- 捕获Exception并处理
- 不捕获但通过throws声明
- 通过throws声明仍需要在上层捕获
- main()是最后捕获Exception的方法
总结
- Java使用异常来表示错误,并通过try{...}catch{...}捕获异常
- Java的异常是class,并且从Throwable继承
- Error是无需捕获的严重错误
- Exception是应该捕获的可处理的错误
- RuntimeException无需强制捕获,非RuntimeException(Checked Exception)需强制捕获,用throws声明。
2. catch、finally
catch、finally概述
- catch的顺序非常重要:子类必须写在前面
- finally语句块保证有无错误都会执行
- multi-catch,如果某些异常的处理逻辑相同:
- 不存在继承关系,必须编写多条catch子句
- 可以用“|”表示多种Exception
总结
- catch子句的匹配顺序非常重要,子类必须放在前面
- finally子句保证有无异常都会执行
- catch可以匹配多个非继承关系的异常(JDK>=1.7)
3. 异常的传播
当某个方法抛出异常时:
- 如果当前方法没有捕获,异常就被抛到上层调用方法
- 直到遇到某个try...catch被捕获
- printStackTrace()可以打印出方法的调用栈
如果一个方法捕获了某个异常后又在catch子句中抛出新的异常,就相当于把抛出的异常类型“转换”了:
- 新的Exception可以持有原始异常信息
在抛出异常前:
- finally语句会保证执行
- 如果finally语句抛出异常,则catch语句不再抛出
- 没有被抛出的异常称为”被屏蔽“的异常(Suppressed Exception)
处理Suppressed Exception
如何保存所有的异常信息?
- 用origin变量保存原始异常
- 如果存在原始异常,用addSuppressed()添加新异常
- 如果存在原始异常,或者新异常最后在finally抛出
如何获取所有的异常信息?
- 用getSuppressed()获取所有Suppressed Exception
总结
- printStackTrace()可以打印异常的传播栈,对于调试非常有用
- 捕获异常并再次抛出新的异常时,应该持有原始异常信息
- 如果在finally中抛出异常,应该把新抛出的异常添加到原有异常中
- 用getSuppreessed()可以获取所有添加的Suppressed Exception
- 处理Suppressed Exception要求JDK>=1.7
4. 自定义异常
JDK定义的常用异常
- RuntimeException
- NullPointerException
- IndexOutOfBoundsException
- SecurityException
- illegalArgumentException
NumberFormatException
- IOException
- UnsupportedCharsetException、FileNotFoundException、SocketException...
- ParseException、GeneralSecurityException、SQLException、TimeOutException...
自定义异常
自定义新的异常类型:
- 从适合的Exception派生
- 从RuntimeException派生——继承RuntimeException不需要强制捕获自定义异常,不需要再方法中声明要抛出的异常
自定义新的异常关系树:
- 从适合的Exception派生BaseException
- 其他Exception从BaseException派生
自定义异常应该提供多个构造方法:
总结
- 自定义异常应该从合适的Exception派生
- 推荐RuntimeException
- 自定义异常应该提供多个构造方法
- 可以使用IDE根据父类快速创建构造方法
5. 日志管理---断言
断言概述
- 断言Assertion是一种程序调试方法
- 使用assert关键字
- 断言条件预期为true
- 如果断言失败抛出AssertionError
- 可选的断言消息
- 断言特点
- 断言失败时会会抛出AssertionError,导致程序结束退出
- 不能用于可恢复的程序错误
- 只应该用于开发和测试阶段
断言的使用
- 启动断言(JVM默认关闭断言指令)
- 给JVM传递-ea参数启动断言
- 可以指定特定的类启动断言-ea:com.sc.sample.TestAssert
- 可以指定特定的包启动断言-ea:com.sc...
- 具体步骤如下:
(1)编辑代码,直接运行
(2)JVM中配置,输入 ea:包名路径.类名
(3)再运行
总结
- 断言是一种调试方式,断言失败会抛出AssertionError
- 只能在开发和测试阶段启用断言
- 对可恢复的错误不能使用断言,而应该抛出异常
- 断言很少被使用,更好的方法是编写单元测试
6. 日志管理--JDK Logging
Logging概述
问:什么是日志Logging?
- 为了取代System.out.println();
- 可以设置输出样式
- 可以设置输出级别,禁止某些级别输出
- 可以比呃呃重定向到文件
- 可以按包名控制日志级别
JDK Logging:JDK内置的Logging,在java.util.logging包下
JDK Logging概述
JDK Logging定义了7个日志级别:
- SEVERE
- WARNING
- INFO —— 默认级别
- CONFIG
- FINE
- FINER
- FINEST
JDK Logging的局限性:
- JVM启动时读取配置文件并完成初始化
- JVM启动后无法修改配置
- 需要在JVM启动时传递参数: -Djava.util.logging.config.file=config-file-name
JDK Logging实现
总结
- 日志是为了替代System.out.println();可以定义格式,重定向到文件等
- 日志可以存档,便于追踪问题
- 日志记录可以按级别分类,便于打开或关闭某些级别
- 可以根据配置文件调整日志,无需修改代码
- JDK提供了Logging:java.util.logging
7. 日志管理--Commons Logging
Commons Logging概述
Commons Logging是Apache创建的日志模块:
- 可以挂接不同的日志系统
- 可以通过配置文件指定挂接的日志系统
- 可以自动搜索使用Log4j
- 使用JDK Logging(JDK>=1.4)
Commons Logging定义了6个日志级别:
- FATAL
- ERROR
- WARNING
- INFO —— 默认级别
- DEBUG
- TRACE
Commons Logging的使用
- 创建Commons Logging的3种方法
- 在静态方法种引用Log: static final Log log=LogFactory.getLog(类名.class);
- 在实例方法中引用Log:final Log log=LogFactory.getLog(getClass());
- 在父类中实例化Log:protected final Log log=LogFactory.getLog(getClass());
- commons Logging使用详细步骤如下
(1)添加commons-logging-1.2.jar——可自行在commons.apache.org官网下载--传送门--
注:在Eclipse下创建lib目录将jar包添加进去,右击jar包Build Path即可
(2)编写代码测试
总结
- Commons Logging是使用最广泛的日志模块
- Commons Logging的API非常简单
- Commons Logging可以自动使用其他日志模块
8. 日志管理--Log4j
Log4j概述
- Log4j是目前最流行的日志框架:1.x——Log4j;2.x——Log4j2
- 3种位置输出流程如下:
- Commons Logging如果在classpath种发现了Log4j,就自动使用Log4j
实践推荐
- 始终使用Commons Logging接口来写入日志
- 开发阶段无需引入Log4j
- 使用Log4j只需要把正确的配置文件和相关jar包放入classpath即可
- 使用配置文件可灵活修改日志,无需修改代码
Log4j的使用
- 使用步骤如下:
(1)添加Log4j的jar包支持——可自行在Log4j官网--传送门--下载
(2)编写代码
注:于Commons Logging的代码完全相同,不需要修改
(3)***编写log4j2.xml文件——重点
(4)运行结果显示
总结
- 通过Commons Logging实现日志,不需要修改diamagnetic即可使用Log4j
- 使用Log4j只需要把log4j2.xml和相关jar放入classpath
- 如果要更换Log4j,只需要移除log4j2.xml和相关jar
- 只有扩展Log4j时才需要引入Log4j的接口
日志处理这块只需第一次配置完毕基本上就不需要管了,以后对日志的管理只需要修改以下log4j2.xml文件即可,非常的方便简单。注意博客中实践推荐等内容,保证高效的开发!——JavaSE知识将在近期更新,欢迎关注?---知飞翀---?
谢谢阅读 ----知飞翀