异常的基本概念

一、异常的基本概念
异常就是程序执行过程不希望出现的问题,异常的对立面就是正常。如果执行过程中出现了异常,jvm就会终止,应用程序随之终止。
二、java中异常的结构
Throwable类是Java语言中所有错误和异常的超类。它有两个子类,一个是Error表示执行中的错误,一个是Exception表示程序执行中可以被捕获并处理的异常。
Error:表示程序中的严重问题,此种问题不能捕获并处理,听天由命,比如OutOfMemoryError 表示内存溢出,只能预防。Error对于程序是致命的。
Exception:表示可以捕获并处理的异常,它是设计必须关注的异常类型。学习的重点在于Exception及子类所描述异常类型的处理方式。
三、java中的异常处理(Exception)
Exception下面有两个子类,分别是编译期异常和运行时异常。

在这里插入图片描述
在这里插入图片描述

编译时异常:会被编译器检查的异常,这种异常在编码就会出现,必须在程序中立即处理,要么用try 语句包起来,要么抛出去(谁调用谁处理)。如果不处理,程序不能正常编译不会生成字节码文件。
运行时异常:编译器不理会,这种异常会在程序执行时产生,它也是不合理的,因此在编程时需要考虑它,如果未考虑可能会在测试阶段被发现成为一个bug。

1、运行时异常的例子

   int a = 10,b = 0;
int result = a/b;
System.out.println("a/b="+result);

以上程序执行会产生运行时异常
java.lang.ArithmeticException: 是异常产生时由jvm创建的对应于该异常的异常对象,在java中不同的异常都有对应的对象,该对象由 jvm创建并抛出。
/ by zero:异常信息,它封装在异常对象中。

public static void main(String[] args) {
    int a = 10,b = 0;
    cal(a, b);
}
//该方法会产生异常
static int cal(int a,int b){
    int result = a/b;
    return result;
}

java.lang.ArithmeticException: / by zero:上述已讲

at RuntimeExceptionTest.cal(RuntimeExceptionTest.java:9)//异常产生的源头
at RuntimeExceptionTest.main(RuntimeExceptionTest.java:5)

以上两行异常信息说明了当异常产生时,jvm内部会生成一个异常跟踪堆栈,栈中的每个元素表示当前异常在代码中生成的位置,这说明当异常产生时,异常是逐层抛出的,如果产生异常时该异常未被处理就会被向调用它的位置(方法栈中下面的栈帧对应的方法)进行抛出。
以后在程序执行中如果出现这样的异常栈信息,就要去查找异常产生的源头及相关方法的调用次序。

2、异常的捕获和处理
我们在设计时如果已经预测到某部分代码在执行时可能会产生异常就应当对这块代码进行异常的捕获及相应的处理。
如果异常未被捕获,那么程序执行到此就结束了,对于用户来讲就感到莫名其妙。
捕获和处理异常的语句是:

  Try{
       可能会出异常的语句块;
}catch(异常类型参数 参数名){//异常类型要与产生的异常类型匹配,匹配是指符合向上转型的条件,catch可以有多个
   处理异常的语句块
}finally{
   释放资源;
}


在这里插入图片描述

public static void main(String[] args) {
    int a = 10,b = 0;
    cal(a, b);//接受cal方法抛出的异常,后面的代码不执行,把异常抛给jvm,异常信息是jvm打印的
    System.out.println("main方法产生异常后");
}
//该方法会产生异常
static int cal(int a,int b){
    int result = a/b;//此处抛异常,直接抛给main,后面的代码不执行
    System.out.println("cal方法产生异常后");
    return result;
}

加上try语句

try {
  result = a/b;
} catch (Exception e) {
    e.printStackTrace();
} finally {
    System.out.println("finally执行了");
}

3、try catch finally之间的关系
(1)try 可以与catch或finally搭配使用,try{}catch{} try{}finally{}
(2)Catch 不能没有try,它不能单独有。
(3)Finally 也不能没有try,它也不能单独用。
(4如果有finally,无论异常是否被catch处理,finally中的语句都会执行,哪怕在catch中有return,finally都会执行

4、编译时异常
所谓编译时异常就是编译器会检查的异常情况,如果编译器认为某个语句必须要进行捕获处理,这种异常就是编译时异常。

//创建一个文件输出流对象,此时编译器会检查出需要捕获处理的异常
//相关语句必须用try catch包起来,否则编译不通过。
try {
    FileWriter fw = new FileWriter("d://temp//a.txt");
} catch (IOException e) {
    e.printStackTrace();
}

结论:在编程时,程序员重要考虑的是,哪里可能会出现运行时异常。

5、异常的抛出
有时候,某个方法可能会出现异常,程序员心里有清楚,但是它可能认为此异常的产生与自已没有关系,可能是由调用该方法的程序造成的。此人认为,这种异常应该由调用者去捕获处理。
如果不希望处理异常,可以通过 throw 语句把异常抛出去,交给调用者处理。这种异常类型往往是运行时的异常。

   public static void main(String[] args) {//B写的方法
       int a = 10,b=0;
       try {
           div(a, b);
       } catch (Exception e) {
           e.printStackTrace();
           System.out.println("异常处理了,给A表示不好意思");
       }finally {
           System.out.println("finally执行");
       }
       System.out.println("程序执行结束");
   }

static int div(int a,int b){//A写的方法
    if(b == 0){
        throw new RuntimeException("兄弟,b 不能是 0,你个弱智!");
    }
    int result = a/b;
    return result;
   }

6、抛出编译时异常
编译时异常必须处理,如果设计者认为产生编译时异常的原因是由调用者造成的,也可以把此种异常抛出,让调用者处理。抛出编译时异常要在方法声明的后面添加 throws 异常类型,此是方法的调用者要么去处理该异常要么继续向上抛出异常。

static void writeFile(String fileName) throws IOException{

    //此处的编译时异常也可以抛出
    FileWriter fw = new FileWriter(fileName);}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值