Java学习笔记-异常处理

个人博客Faye’s Blog

一、处理异常

1.异常层次

  所有异常都由 Throwable 继承而来。

exception

Error 类描述了 Java 运行时系统的内部错误和资源耗尽错误。Exception 层次分为 RuntimeException 和其他异常。

派生于 RuntimeException 的异常包含:

  • 错误的类型转换
  • 数组访问越界
  • 访问 null 指针

不是派生于 RuntimeException 的异常包含:

  • 试图在文件末尾后读取文件
  • 试图打开一个不存在的文件
  • 试图根据给定的字符串查找 Class 对象,而该类不存在

“如果出现了 RuntimeException 异常,那一定是你的问题”

派生于 Error 类和 RuntimeException 类的异常称为非受查异常,其他异常称为受查异常

2.声明受查异常

 方法必须声明所有可能抛出的受查异常,但不用声明从 Error 继承的错误(不可控制),不用声明从 RuntimeException 继承的非受查异常(尽量避免)。

  子类覆盖超类的方法,在子类中声明的受查异常不可比超类中的更通用。(若超类方法没有抛出任何受查异常,子类也不能抛出)

3.创建异常类

  一般地,定义的类应该包含两个构造器,一个是默认的,另一个是带有详细信息的构造器

class FileFormatException extends Exception{
    public FileFormatException(){}
    public FileFormatException(String mess){
        super(mess);
    }
}
4.抛出异常

 1.找到或创建合适的异常类

 2.创建该异常类的对象

 3.抛出该对象

二、捕获异常

1.捕获异常

  如果某个异常发生时未在任何地方进行捕获,那么程序就会终止。如果捕获一个异常,必须设置 try/catch 语句块。

  通常,应该捕获那些知道如何处理的异常,而将那些不知怎样处理的异常进行传递。如果要传递异常,就必须在方法首部添加 throws 关键字。

  存在多个 catch 时,子类错误必须写在前面。

2.finally 子句

  不管是否有异常被捕获,finally 子句中的代码都被执行。如果要抛出异常,则先执行 finally 子句,再抛出异常。

建议解耦合 try/catchtry/finally 语句块:

try {
    try {

     } finally {

     }
} catch () {

}

内层的 try 语句,确保 finally 子句的执行。外层的 try 语句确保报告错误,且将报告 finally 子句中出现的错误。

  当利用 returntry 中退出时,在返回前,finally 子句的内容将执行。若 finally 子句中也有 return 语句,将会覆盖之前的返回值。

  finally 子句抛出异常同上述 return 。会抑制 try 中的异常,应该使用异常变量将其暂存,然后调用 addSuppressed,添加原始异常,再抛出。

3.再次抛出异常和异常链

  包装异常,将原始异常设置为新异常的原因。

catch(SQLException e){
Throwable se = new NewException("new exception");
se.initCause(e);
throw se;
}

  Throwable e = se.getCause(); 得到原始异常。

4.带资源的 try 语句
try(Resource ...){
...
}

  try 块退出时,自动调用 .close() 。若 close 方法抛出异常,该异常就会被自动捕获,并用 addSuppressed 方法增加到原来的异常。可以调用 getSuppressed 方法得到 close 方法抛出的异常。

5.堆栈轨迹

  堆栈轨迹(stack trace)是一个方法调用过程的列表。

  • Java 程序终止,未捕获异常时,该列表就会显示。

  • 调用 Throwable 类的 printStackTrace 方法,访问堆栈轨迹的信息

  • 使用 getStackTrace 方法,得到 StackTraceElement 对象的数组。

6.使用异常机制技巧

1.异常处理不能代替测试

2.不要过分细化异常

3.利用异常层次结构:

  不要只抛出 RuntimeException 异常,不要只捕获 Throwable 异常,否则会使程序更难读。将一个异常转换成另一个更合适的异常时不要犹豫。

4.不要压制异常

  若认为异常很重要,就应该处理

5.早抛出,晚捕获

  • 检测错误时,苛刻比放任更好。在出错的地方抛出,比在后面抛出其他异常好。

  • 不要害怕传递异常

三、断言

  断言机制允许在测试阶段向代码中插入一些检查语句,代码发布后,这些插入的检查语句会被自动移走。

assert 条件;

assert 条件:表达式;

会对表达式进行检测,若为 false ,则抛出一个 AssertionError 异常。(表达式会传入 AssertionError 构造器,转换成一个消息字符串)。

四、日志

基本日志:

使用全局日志记录器 Logger.getGlobal().info("test log");。在适当的地方调用Logger.getGlobal().setLevel(Level.OFF);,会取消所有日志。

五、调试技巧

1.可以打印或记录任意变量的值

2.可在每个类防止一个单独的 main 方法,可以对每个类进行单元测试。

3.利用 Throwable 类的 printStackTrace 方法。

  可从异常对象获得堆栈轨迹。(可以在任何位置插入 Thread.dumpStack(); 会的堆栈轨迹,无需异常)

我的个人博客Faye’s Blog

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值