错误处理

1 如果遇到了 错误, 应该
返回到一种 安全的状态,并执行一些其他的命令
允许保存所有操作的结果, 并以妥善的方式 终止程序
2 异常对象都是 Throwable 类的 一个实例,用户还能自己创建 异常类
image.png
Error 描述了 Java运行过程中 系统的内部错误 和 资源耗尽错误 (只能告知用户 并 安全终止程序。不可控制)
RuntimeException 是由程序错误 导致的(如果出现运行时异常,一定是研发人员的问题,应该避免出现该异常)
如 错误类型转换,访问越界,null异常 等
IOException则表示其他异常 (需要设置处理方式)
如 打开不存在的文件,查找不存在的Class对象
Error和 RunTimeException 为 unchecked 异常, 不应该出现(非受查异常)
其他异常 为 checked异常,要设定一定的处理方式
3 如果遇到了无法处理的情况,那么Java的方法可以抛出一个异常
方法应该在其首部声明所有可能抛出的受查异常
4 对于一个以及存在的异常类,需要抛出的时候 构建实例 并用 throws 抛出 即可
5 创建自己的异常类,只需要定义一个派生于 Exception的类 即可 实际上需要定义两个构造器方法即可

  1. class MyException extends Exception{
  2. public MyException(){}
  3. public MyException(String gripe){super(gripe);}
  4. }

6 e.getMessage() 可以获得 Throwable 对象的 详细错误信息

捕获异常

1 如果没有任何地方捕获异常,程序会终止执行
2 在方法内通过 try Catch 语句捕获异常
如果 try的语句内 没有异常,会跳过catch子句
3 也可以将异常 抛给调用者 ,在方法首部声明即可
4 如果覆写了一个没有抛出异常的方法,就必须捕获可能出现的异常
5 可以写多个catch子句来捕获多个异常

  1. try{}
  2. catch(FileNotFoundException e){}
  3. catch(IOException e){}

6 在catch子句中也可以抛出异常
如,想要改变异常的类型,建议抛出的新异常se调用initCause方法 保存原始异常e
或者想 在本方法记录下该异常,并再次抛出给调用者
7 可以加一个finally子句,无论是否有异常,finally子句都会被调用,用于 关闭一些该方法打开的资源
8 建议 将 try catch 和 try finally 进行解耦 这样结构更清晰 ,而且还能处理 finally子句的异常

  1. try{
  2. try{
  3. }finally{
  4. }
  5. }catch(){
  6. }

9 当finally子句 包含 return 的时候,try 中的 return 先执行, 该值会被记录, finally子句的return后执行, 会覆盖掉记录的返回值
10 可以编写带资源的 try 语句,try退出时 会自动调用 close()

  1. try(Resource res = ...)
  2. {}
  1. 这个是为了解决 try语句的异常 finally的异常 都存在 但需要捕获的是 try 语句异常的时候<br />11 通过e.getStackTrace() 可以获得StackTraceElement一个数组,该对象 包含文件名 和行号,类名和方法名 等信息

断言

1 断言机制允许在测试期间向代码中插入一些检查语句。当代码发布时,这些插入的检测语句将会被自动地移走
2 有两种形式,assert 条件; 或者 assert 条件 : 表达式;
“表达式”部分的唯一目的是产生一个消息字符串
如果条件结果为false 会抛出AssertionError 异常
3 在默认情况下,断言被禁用。可以在运行程序时用-enableassertions或-ea选项启用

日志

1 要生成简单的日志记录,可以使用全局日志 记录器
Logger.getGlobal().info(“xxxxxx”)
Logger.getGlobal().setLevel(Level.OFF) 会关闭全局日志记录器
2 不要把所有的日志放在一个记录器下,通过getLogger方法创建 或者 获取记录器
private static final Logger myLogger = Logger.getLogger(“com.mycompany.app”)
未被任何变量引用的日志记录器可能会被垃圾回收,所以需要通过静态变量来存记录器
3 与包名相比,日志记录器的层次性更强,父记录器 和 子记录器 会 共享某些 属性 如 日志记录器 级别
4 有7个日志记录器级别
SEVERE WARNIG INFO // CONFIG FINE FINER FINEST
默认情况下,只记录前三个级别 Level.ON 开启全部级别, Level.OFF 关闭全部级别
logger.warning(..) logger.info(…)
5 默认情况下,日志记录器将记录发送到ConsoleHandler中,并输出到 System.err 流中,日志记录器还会将记录发送到父处理器中
可以通过 logger.setUseParentHandlers(false) 来不向父处理器发送
6 处理器也有 日志处理 级别 日志级别 必须高于记录器和处理器 才行
7 要想将日志记录发送到其他地方,就要添加其他的处理器,如 FileHandler 和 SocketHandler

  1. FileHandler handler = new FileHandler();
  2. logger.addHandler(handler);

可以通过设置日志管理器配置文件中的不同参数
image.png
8 还可以通过扩展Handler类或StreamHandler类自定义处理器
9 过滤器根据日志记录的级别进行过滤。每个日志记录器和处理器都可以有一个可选的过滤器来完成附加的过滤
可以实现 filter 接口覆写 boolean isLoggable(。。)接口 判断 某个日志是否通过过滤
安装过滤器 只需要调用 logger 和 handler 的setFilter 即可,记录器和处理器同一时刻只能有一个过滤器
10 Handler类可以生成文本和XML格式的日志记录,也可以自定义格式
需要扩展 Formater类 并覆写 format方法,
通过setFormatter 方法 将 格式化器 安装在 处理器中