DAY06--异常

异常

异常有“我对此感到意外”的含义,代表程序执行出错,专业点的描述:异常是指阻止当前方法和作用域继续执行的问题(是个问题,哈哈)

异常分类

Throwable:两个重要的子类,Error(JVM内部错误或者是资源耗尽错误),Exception(异常)

  • Error是程序无法处理的错误,而Exception则是程序本身可以处理的异常
  • Exception分RuntimeException和其他异常
    • RuntimeException是由程序错误导致的
    • 其他异常则是程序本身没有问题,但是I/O之类的错误导致的异常

按照受不受编译器检查异常分:受检查异常和非检查异常

  • 非受检查异常包括:Error类和RuntimeException下的都是属于非受检查异常
  • 编译器会为每个受检查异常检查是否配有异常处理器,也就是说非受检查异常没有异常处理器也是行的,至少编译器不管。
  • 受检查异常,这种异常是无法预测的,所以编译器必须管,写在try catch中

常见的异常情况:

  • 用户输入错误
  • 设备错误
  • 物理限制
  • 代码错误
    • 如下标越界

异常对象的生成

  • 虚拟机自动生成
  • 手动创建

为什么需要异常处理?

  • 因为我们希望程序运行期间出错时系统能够返回一种安全状态(不能崩了),同时保存用户的操作结果

异常处理的任务:将控制权从异常产生的地方转移到能够处理异常情况的处理器上

异常处理机制的作用

  • 发生异常时强制程序停止运行,并告诉我们出了什么问题,(理想情况下甚至能强制处理问题,)并回到稳定状态

发生异常时会有什么行为

  • 跟其他对象创建一样,会在堆上new一个异常对象,当前执行路径会被终止,会从当前环境中弹出对异常对象的引用,此时,异常处理机制接管程序,并寻找一个恰当的地方来执行程序,这个恰当的地方即异常处理程序,它的作用是使程序继续运行,要么换一种方式运行

异常构造器

  • 默认构造器
  • 以String作为参数,以便能把相关信息放入异常对象的构造器(以后可以提取出来)
捕获异常

try块

  • 作用:(捕获异常)在方法内部抛出异常,或者是在方法内部调用其他方法抛出了异常,那么这个方法会在抛出异常的时候结束,如果不希望该方法结束,则是可以在方法内设置一个特殊的块来捕获异常,又因为这个块总是"尝试"各种(可能产生异常的)方法调用,故称为"try"块

catch块(异常处理程序)

  • 作用:(处理每个捕获异常)抛出的异常必须在某处得到处理,这个地点就是异常处理程序,针对每个要捕获的异常,都需要准备相应的异常处理程序,每个catch子句看上去都是接受一个或者是仅能接收一个特殊类型的方法

终止与恢复

  • 终止模型
    • JAVA和C++终止的模型,他假设抛出的异常非常关键,以至于无法返回到异常发生的地方继续执行
  • 恢复模型
    • 指异常处理程序的主要工作是为了修正错误,然后尝试重新调用出问题的方法,并认为第二次能成功

常见的java异常处理的方式

  • try-catch-finally
  • throws+异常类型

注意事项:

  • try块,如果没有try块,则是必须要准备一下finally块

  • finally块,不管有没有捕捉到异常,在try块或则是在catch块中遇到了return,finally块也会在return 之前执行,只要进入到try块就会执行finally块

创建自定义异常
class SimpleException extends Exception{
//    自定义异常类,使用默认的异常构造器
}
public class Myexception {
    public static void f() throws SimpleException {
        System.out.println("throw SimpleException from f()");
        throw new SimpleException();//百分百产生异常,且不处理,哈哈
    }

    public static void main(String[] args) {
        try {
            f();
        } catch (SimpleException e) {
//            e.printStackTrace();//打印栈轨迹,将打印从异常抛出处到方法调用处,不打印也行
            System.out.println("catch it");
        }
//        由于有异常捕获处理,故这行能够执行
        System.out.println("hello world");
    }
}
// output
throw SimpleException from f()
catch it
hello world
异常与记录日志(待续)

重新抛出异常

  • 为什么需要重新抛出异常?
    • 我希望把异常抛给上一级环境中的处理程序

异常说明

  • JAVA鼓励方法声明潜在的异常,以便让方法调用者可以捕获所有的异常
  • 用throws来声明可能抛出的异常类型,void f(){…}则是表明不会抛出任何异常(除了RuntimeException继承来的异常,他们可以在没有异常声明的情况下抛出,哈哈RuntimeException真的很任性)
  • 代码必须跟异常声明保持一致,如果方法里面的代码产生了异常却没有处理,编译器则会提醒你
    • 要么处理这个异常
    • 要么在方法中声明异常

捕获所有的异常与获取信息

  • 你用Exception就行了,
  • getMessage方法来获取详细信息,toString方法则是返回对Throwable的简单描述+详细信息(知道的真多)
  • printStackTrace方法则是会打印Throwable对象和他的调用轨迹
//输出到标准错误
printStackTrace()
//这两个重载方法可以指定输出流
printStackTrace(PrintStream)
printStackTrace(PrintWriter)
异常链
  • 为什么需要异常链?

    • 如果你捕获到一个异常后希望抛出另一个异常,而且希望把原始异常信息保存下来
  • 标准异常类即预定义异常类,

  • 子类抛出的异常范围不能比父类大

    • 如果父类方法中没有说明要抛出异常,那么重写父类方法时,你只能在子类方法中直接将异常捕获,不能throws
  • 异常是Exception类型的对象,异常对象:里面封装了错误信息,异常总是抛给调用方,会抛出异常的方法必须声明他可能会这样做,用throws,

异常与构造阶段
  • 对应构造阶段可能抛出异常,而且要求清理的类,最安全的方式是使用嵌套的try,(即在合适的时候才触发finally)
  • JAVA的缺陷:除了内存清理外,所有的清理不会自动发生

异常匹配

  • 异常处理机制会按照代码书写顺序查找最近的处理程序,找到匹配的程序后,就认为异常得到了处理,不再查找

把“受检查异常”转换成“不受检查异常”

  • 可以对异常进行包装,生成新的异常
try {
// something
} catch (Exception e) {
    throw new RuntimeException(e);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值