JAVA基础:异常与异常对象,抛出异常,自定义异常,异常处理,受检与非受检异常

1 什么是异常

  • 宏观 : 程序在编译和运行时出现的问题(错误)

    • 编译异常 :javac 语法问题

    • 运行异常: java 逻辑问题 (空指针异常,数组下标越界异常)

  • 微观: 编码时所谓的异常,实际上是异常对象。

    运行时产生了一个异常,实际上就是产生了一个异常对象

  • 错误(问题)代表的是一种情况,一种现象,一种表现 。 异常(对象)是对这种现象的描述

2 异常对象的特点

  • 有异常对象,就一定会先有异常类

  • 异常对象是一个可以被抛出的对象,所有的异常类都要继承一个Throwable父类

  • 根据问题的严重程度,将异常(描述)分为两类

    1. Error 所有继承Error父类的异常,属于Error异常,表示这个问题有些严重

      一般无法再程序运行过程中解决,建议关闭程序,慢慢解决

      栈内存溢出 StackOverFlowError

    2. Exception 所有Exception父类的异常,属于Exception异常,表示这个问题不太严重

      可以在程序运行时给与解决方案,使得程序可以继续执行

      空指针异常 NullPointerException

  • 无论Error还是Exception,都必须是可以抛出的,都继承Throwable

3 抛出异常(对象)

  • 异常情况一般都是伴随着判断产生

public void t1(){
    int age = scanner.nextInt();
    if(age < 0 || age >= 200){
        //这就是一种错误的年龄输入情况(您输入的年龄非法)
        //此时在程序运行时产生了一个问题(异常情况)
    }
    
}

 

  • 出现问题后,如果解决方案明确,就直接在方法中使用代码解决 , 此时与异常无关

  • 如果解决方案不明确(一般是在封装的方法中), 将可以对问题给与描述(产生异常对象),并将其抛给当前方法的调用者,让调用者来处理

3.1 JDK提供的异常

  • 所谓的给与异常描述,就是创建异常对象

  • 要想创建异常对象,需要先有异常类

  • JDK提供了很多异常描述(异常类)

    • NullPointerException

    • ArrayIndexOutOfBoundsException

    • StackOverflowError

    • FileNotFoundException

    • ClassNotFoundException

  • 产生异常描述就是new对象

    new NullPointerException()

  • 使用throw关键字抛出异常对象,抛给当前方法的调用者

public void t1(){
    String path = scanner.next();//输入一个文件地址
    findFile(path);
}

public void findFile(String path){
    //根据调用者传递的文件路径,帮调用者寻找文件
    if(path ... ){
        //没有找到对应的文件
        throw new FileNotFoundException();
        //无法执行,不可达的代码
    }
}

 

注意

throw关键字执行的时候,会结束当前方法,为调用者返回一个错误描述(异常对象)

throw关键字的作用与return类似

3.2 自定义异常类

  • 我们可以自定义异常,来描述出现的问题

    1. 自定义异常类 , 继承异常相关的父类(Throwable,Exception , Error)

      一般异常的名字就体现了错误的情况,可以在配合注释进一步说明

/**
	当年龄小于0或大于150时,抛出这样的异常
*/
class AgeOutOfBoundsException extends Exception{}

 2.通过有参构造方法,为异常提供更为详细的描述信息(可选)

class AgeOutOfBoundsException extends Exception{
    public AgeOutOfBoundsException(){}
    
    public AgeOutOfBoundsException(String msg){
        super(msg);
    }
}

3.使用throw 抛出异常

public void t1(int age){
    if(age <0 || age > 150){
        throw AgeOutOfBoundsException("您提供的年龄是"+age+",但他超过了基本的年龄范围,基本年龄范围是[0,150]");
    }
}

4 处理异常

  • 我们调用其他工具类时,传递了一些信息。

  • 工具类在使用我们提供的信息执行功能时出现了问题,不知道该如何处理

  • 就会将问题形成一个异常对象描述,并抛给我们(此时我们是调用者)

  • 这个时候我们应该如何处理异常呢?

  • 异常处理的过程是:要么我们在当前的方法中处理,要么就继续向上抛,抛给我们的调用者处理

    • 如果一直都没有方法处理,最终会抛给JVM。JVM会打印错误信息并停止程序

    • 过程中如果一个方法无法处理这个异常

      1. 重新创建一个异常对象,手动throw抛给调用者

      2. 不做任何处理,会自动抛给调用者

  • 我们如何处理异常?

    1. 在方法中,使用try{}包裹可能产生异常对象的代码

      运行时一旦产生了异常对象,try就会对其进行捕获

      会将异常对象交给对应的catch来处理

public void t1(int age){
    if(age < 0 || age > 150){
        throw new AgeOutOfBoundsException();
    }
}

//----------------------------
  
public void t2(){
    int age =scanner.nextInt();
    try{
    	t1(age);
    }
}

              2.在try{}代码块后面跟着catch{}来处理指定的异常问题

                在try的后面跟多个catch,来处理不同的异常情况

public void t2(){
    int age =scanner.nextInt();
    try{
    	t1(age);
        。。。。
    }catch(NullPointerException e){
        //根据空指针异常情况来处理异常
    }catch(ArrayIndexOutOfBoundsException e){
        //根据数组下标越界异常情况来处理异常
    }catch(AgeOutOfboundsException e){
        //根据年龄越界异常情况处理异常
    }
}

注意:如果多个catch处理的异常对象存在继承关系

要求对父类异常情况的处理必须在catch、列表的后面

try{
    
}catch(NullPointerException e){
    
}catch(Exception e){
    
}

3.在try和catch的后面,可以跟有finally{}块,作为try和catch的统一出口

如果有一段代码,在try中也要执行,在catch也要执行,就可以将其写在finally中。

try{
    a
        b
        c
        
}catch(){
    a1
        a2
        a3
        dddd
}finally{
    dddd
}

注意 try-catch-finally组合

  • try-catch-finally可以通过使用,按照上述的顺序

  • try的后面可以没有catch,但需要紧跟finally

try{
    
}finally{}
  • try-catch不能单独存在,catch必须跟在try的后面

  • 一旦有finally,无论执行try,还是执行catch,finally中代码一定执行。哪怕try和catch中有return

try{
    return 10 ;
}catch(){
    return 20 ;
}finally{
    System.out.println("--------------------------");
}

 如果try,catch和finally中都有return,最终返回的finally中的值。

try{
    return 10 ;
}catch(){
    return 20 ;
}finally{
    return ;
}

5 受检异常与非受检异常

  • 所有继承RuntimeException的类,都称为非受检异常

    在编码时,对可能产生异常的代码不必须提前做处理或声明,但可以做处理或声明

  • 其余的异常类,都称为受检异常,要求在编码的时候:

    1. 如果方法能处理异常,必须对可能产生异常的代码提前做try-catch处理

    2. 如果方法不能处理异常,会抛给调用者,由调用者处理,就需要调用者提前try-catch处理,当前方法需要使用throws关键字声明(告诉调用者),当前方法有可能产生一个无法处理的受检异常,你的try-catch

    3. FileNotFoundException就是一个受检异常

public void t1(){
    t3();
    
    try{
        t2();
    }catch(FileNotFoundException e){
        
    }
    
}

public void t2()throws FileNotFoundException{
    new FileInputStream("c:/z/1.txt");
}

public void t3(){
    try{
    	//这可能会抛出一个FileNotFoundException 受检异常
    }catch(FileNotFoundException e){}
}

 

注意

  • 一个方法可以使用throws声明多个受检异常,使用逗号隔开

public void t1()throws Exception1 , Exception2 , ...{}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值