Java笔记03

Java的异常

  • 异常是一种class, 本身带有类型信息
  • 异常可以在任何地方抛出, 但只需要在上层捕获
  • 最先来自于Throwable, 分为ErrorException
  • Error: 严重错误, 系统无能力处理
    • OutOfMemoryError: 内存溢出异常
    • NoClassDefFoundError: 无法加载class异常
    • StackOverflowError: 栈溢出
  • Exception: 运行时错误, 可以被捕获
    • NumberFormatException: 数值类型的格式错误
    • FileNotFoundException: 未找到文件
    • SocketException: 读取网络失败
    • NullPointerException: 空指针异常
    • IndexOutOfBoundsException: 数组索引越界
  • Exception分成:
    • RuntimeException以及它的子类
    • 非RuntimeException(包括 IOException, ReflectiveOperationException)
  • 必须捕获的异常(Checked Exception): Exception及其子类, 不包括RuntimeException
  • 不需要捕获的: Error及其子类, 以及RuntimeException

捕获异常(java的异常)

  • 定义的时候, 进行throws, 表示可能抛出的类型
  • 可能抛出的异常, 都必须捕获
  • 所有的异常, 最终在main()中捕获, 不会出现漏写的情况
  • public static void main(String[] args) throws Exception {: main方法可以抛出所有异常, 但一旦抛出, 程便终止运行
  • 异常要有最基本的处理: e.printStackTrace()打印异常栈

捕获异常

  • 可以同时捕获 多个语句
  • catch语句, 可以进行不同类型的捕获
  • catch的顺序非常重要, 子类必须在前面

finally

  • 保证有无错误, 都会执行
  • 不是必须的, 可写可不写
  • 总是在最后执行
  • 某些情况下, 可以没有catch, 直接使用finally进行捕获, 但是就要声明可能抛出的异常

捕获多种异常

  • 多条相同catch可以一起实现
  • } catch ( IOException | NumberFormatException e ) {

抛出异常

  • 异常不断向上抛出, 直到被捕获
  • 捕获后再抛出其他类型的, 进行类型转换
  • 为了保存异常信息: 需要将原始Exception实例传进去
  • Throwable.getCause(): 获取原始异常
  • 异常抛出, 不影响finally执行, jvm优先执行finally
  • finally也抛出异常, 就会把catch中的异常屏蔽

自定义异常

  • 自定义一个baseException作为根异常
  • 建议根异常从RuntimeException
class BaseException extends RuntimeException {
  public BaseException() {
    super();
  }
  public BaseException(String message, Throwable cause) {
    super(message, cause);
  }
  public BaseException(String message) {
    super(message);
  }
  public BaseException(Throwable cause) {
    super(cause);
  }
}

class UserNotFoundException extends BaseException {
}

class LoginFailedException extends BaseException {
}

使用断言

  • 断言自动忽略, 使用enableassertions进行启用
  • java -ea Main.java
  • -ea:com.itranswarp.sample.Main: com.itranswarp.sample.Main这个类使用断言
  • -ea:com.itranswarp.sample...: com.itranswarp.sample这个包使用断言
  • 断言很少被使用, 更好的方法是使用单元测试

使用JDK Logging

  • 日志替代System.out.println
  • 日志分成各个级别

使用Common Logging

  • 静态方法中使用Log, 通常定义一个静态类型变量
public class Main {
static final Log log = LogFactory.getLog(Main.class);
   static void foo() {
   log.info("foo");
   }
}
  • 实例方法中使用Log, 通常定义一个实例变量
public class Person {
  // 使用getClass()  子类可以直接使用该log
    protected final Log log = LogFactory.getLog(getClass());

    void foo() {
        log.info("foo");
    }
}
  • 提供重载方法info(String, Throwable)进行日志记录

使用Log4j

  • 组件化的日志系统
  • 通过不同的Appender输出到不同的目的地
  • 通过Filter来进行需要输出哪些日志
  • 通过Layout进行格式化信息
  • 并不关心API, 使用配置文件
  • 开发阶段使用

使用SLF4J和Logback

  • 一种进化的替代品

疑问

  • 同时抛出两种类型的异常怎么办: 猜测, 抛出异常的父类即可
原文地址:https://www.cnblogs.com/zhangrunhao/p/12547302.html