Java中的异常(Exception)

目录

 一、什么是异常(Exception)?

二、解决方案:try-catch

三、异常的概念

 四、异常的体系图(重点)

 小结:

五、常见的五大运行时异常

1、NullPointerException空指针异常

2、ArithmeticException数学运算异常

3、ArrayIndexOutOfBoundsException数组下标越界异常

4、ClassCastException类型转换异常

5、NumberFormatException数字格式不正确异常

 六、编译异常

 七、异常处理机制

1、try-catch-finally

​编辑

2、throws

八、自定义异常

九、throw和throws的区别

目录的图片:

 一、什么是异常(Exception)?

下面代码中的注释写的很清楚。

package com.hspedu.Exception;

public class Exception01 {
    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 0;

        //1.当执行到num1/num2,因为num2 = 0,程序就会抛出异常ArithmeticException。Arithmetic(adj 算术的)
        //2.抛出异常后,程序就退出,因为崩溃了,下面的代码不再执行。
        //3.在2中叙述的情况,在现实中不合理,不应该因为出现了一个不算致命的问题,就导致整个系统崩溃。
        //4.因此java设计者提供了一个叫 异常处理机制 来解决该问题。
        int res = num1/num2;
        System.out.println("程序继续运行......");  //不会输出该句
    }
}

二、解决方案:try-catch

如果一段代码可能出现异常,可以使用try-catch异常处理机制来解决,从而保证程序的健壮性。

下面是try-catch机制的小例子:

package com.hspedu.Exception;

public class Exception01 {
    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 0;

        //1.当执行到num1/num2,因为num2 = 0,程序就会抛出异常ArithmeticException。Arithmetic(adj 算术的)
        //2.抛出异常后,程序就退出,因为崩溃了,下面的代码不再执行。
        //3.在2中叙述的情况,在现实中不合理,不应该因为出现了一个不算致命的问题,就导致整个系统崩溃。
        //4.因此java设计者提供了一个叫 异常处理机制 来解决该问题。
        //5.有了try-catch机制后,即使出现了异常,程序仍然能够运行
        try {
            int res = num1/num2;
        } catch (Exception e){
            //e.printStackTrace();  //这种是标准写法
            System.out.println("出现异常的原因= " + e.getMessage());  //e.getMessage()就是获取异常信息,这样写更舒服一点
        }
        System.out.println("程序继续运行......");  //不会输出该句
    }
}

三、异常的概念

前面的例子就是运行时异常。

 四、异常的体系图(重点)

对下图的解读(只是部分):Throwable类实现了Serializable接口,并继承了父类Object。Error和Exception都是Throwable类的子类,Exception下又分为运行时异常(RuntimeException)和编译时异常(像FileNotFoundException和ClassNotFoundException都是编译时异常)。虚线代表实现类接口,实现是代表继承,该图清晰的体现了继承和实现接口关系。

 

 

 小结:

五、常见的五大运行时异常

1、NullPointerException空指针异常

在需要使用对象的地方用null时,抛出该异常。

继承关系如下图:

 下面是案例:

package com.hspedu.Exception;
//这就是一个空指针异常
public class NullPointerException {
    public static void main(String[] args) {
        String name = null;
        System.out.println(name.length());
    }
}

2、ArithmeticException数学运算异常

当出现异常的运算条件时,抛出该异常,eg:整数除以0的时候。(上面有案例)

 继承关系如下图:

3、ArrayIndexOutOfBoundsException数组下标越界异常

索引为负数or超出数组范围,抛出该异常。

  继承关系如下图:

4、ClassCastException类型转换异常

将对象强制转换为不是实例的子类时,抛出该异常。(涉及到对象的多态)

   继承关系如下图:

5、NumberFormatException数字格式不正确异常

将字符串转换成数值的时,不能适当转换,抛出该异常。

 继承关系如下图:

 六、编译异常

编译异常是指在编译期间,就必须处理的异常,否则代码不能通过编译。

常见的编译异常:

  • SQLException  //操作数据库时,查询表可能发生异常
  • IOException  //操作文件时,发生的异常
  • FileNotFoundException  //当操作一个不存在的文件时,发生异常
  • ClassNotFoundException  //加载类,而该类不存在时,发生的异常
  • EOFException  //操作文件,到文件末尾发生异常
  • IIIegalArgumentException  //参数异常

 七、异常处理机制

异常处理就是当异常发生时,处理异常的方式。

1、try-catch-finally

在代码中捕获发生的异常,自行处理。

模板:

try{
    //代码(可能有异常)
}catch (Exception e){
    //捕获到异常:
    //1.异常发生
    //2.系统将异常封装成Exception对象e,传递给catch代码块
    //3.得到异常对象后,程序员自行处理,在这里可以添加业务逻辑,
    // 或者只是单纯的打印异常也行
    //4.如果没有发生异常,catch代码块不执行
}finally {
    //1.不管try代码块是否有异常发生,始终都要执行final
    //2.所以通常将关闭连接、释放资源的代码,放在finally里面
}

Tips:

(1)如果try代码块可能有多个异常,可以使用多个catch分别捕获不同类型的异常,并作出相应处理。但是要求子类异常写在前面,不然会报错,例如下面的catch(Exception e)就写在了最后,因为如果catch(Exception e)写在前面,在这个catch代码块 就直接捕获了所有异常,下面再写catch不同类型的异常,没有意义。

(2)可以try-finally配合使用,这种做法相当于没有捕获异常,程序会直接崩掉。应用场景是:执行一段代码,不管是否发生异常,都必须执行某个业务逻辑。

try{
    //代码
}finally{
    //总是执行
}    

(3)当try块中的异常发生后,try块中剩下的语句就不再执行,将执行catch块中的语句,如果有finally,还要再执行finally块中的语句。

2、throws

将发生的异常抛出,交给调用者(方法)处理,最顶级的处理者是JVM。

如果一个方法中可能出现异常,但是无法确定怎么处理该异常,则该方法应显式的声明抛出异常,表明该方法不对这些异常进行处理,而是由该方法的调用者负责处理

 解释:JVM调用main方法,main方法调用f1方法,f1方法调用f2方法。当f2方法中出现异常,有两种选择(1.在f2方法中try-catch-finally;2.throws给f1方法),后面的以此类推,最高可以抛给JVM。(JVM处理异常的方式很暴力(JVM说:都不管我也不管),1.输出异常信息;2.退出程序。)(村里除了问题,村长抛给县长,县长抛给市长,市长抛给省长,直到最高层(JVM))

模板:

    //1.在方法声明中用throws语句抛出异常,throws关键字后面的异常类型可以是方法中产生的异常类型,
    //例如FileNotFoundException,也可以是它的父类Exception。
    //2.throws关键字后也可以是异常列表,即可以抛出多个异常。
    // eg:public void f2() throws FileNotFoundException, NullPointerException, ArithmeticException
    public void f2() throws FileNotFoundException, NullPointerException, ArithmeticException {
        //创建了一个文件流对象
        FileInputStream fileInputStream = new FileInputStream("d://a.txt");
    }

Tips:

(1)对于运行时异常,程序中如果没有处理,默认就是throws的方式处理。
(2)子类重写父类的方法时,规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么就是父类抛出的异常的类型的子类型。

(3)在throws过程中,如果有方法try-catch,就相当于处理异常,可以不用throws。

八、自定义异常

当程序中出现某些错误,但该错误信息并没有在Throwable子类中描述处理,此时可以自己设计异常类,用于描述该错误信息。

自定义异常的步骤:

例子:(看下面的例子就能明白自定义异常)

要求是接收Person对象年龄时,要求范围在18~120之间,否则抛出一个自定义异常(要求继承RuntimeException),并给出提示信息。

package com.hspedu.Exception;

public class customException {
    public static void main(String[] args) {
        int age = 80;
        //要求范围在18~120之间,否则抛出一个自定义异常
        if (!(age >= 18 && age <= 120)){
            //这里我们可以通过构造器,设置信息
            //注意这里是throw!!不是throws!!
            throw new AgeException("年龄需要在18~120之间");
        }
        System.out.println("你的年龄范围正确");
    }
}

//自定义一个异常
//1.一般情况下,我们的自定义异常是继承RuntimeException,即把自定义异常做成是运行时异常
//好处是,可以使用默认的默认处理机制
class AgeException extends RuntimeException{
    public AgeException(String message) {  //构造器
        super(message);
    }
}

九、throw和throws的区别

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m1m-FG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值