一、异常的概念

          概念:在Java中,异常是对程序执行过程中发生的不正常情况的一种描述和处理机制。在日常的开发中,难免会出现一些奇奇怪怪的问题,这就需要我们理解异常了。


 二、常见的异常

1、算术异常

 如上所示:在数学计算中0不能做除数,所以报出了算法错误,JVM(java虚拟机)处理了这个异常,ArithmeticException就表示算数异常,出现异常后,后面的代码也不会再执行了。


2、数组越界异常

如图所示:我们数组的大小为3,访问的大小为100下标的元素,这时候就会出现ArrayIndexOutOfBoundException (数组越界异常)。


3、空指针异常

 如图所示:因为数组array指向一个null(空指针),在求数组长度就会报NullPointerException(空指针异常)。


三、异常的结构体系

         异常的种类繁多,为了对不同异常和错误进行分类,Java内部维护了一个异常的体系结构。

由图可知: 

1、throwble:是异常体系的顶层类,其派生出两个重要的子类:Error 和 Exception。

2、Error:是指JVM无法解决的严重问题,比如JVM的内部错误、资源耗尽等。

3、Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行。


 异常的分类:

1、编译时异常:

也称为受检查异常(Checked Exception),例如:IOException、SQLException等

2、运行时异常

也称为非受检查异常(Unchecked Exception),在程序执行期间发生的异常,例如我们之前所写的空指针异常等。

注意:语法性错误不能称之为异常。


四、异常的处理

1、异常的抛出——throw

       在Java中,throw是用于手动抛出异常的关键字,语法如下:

throw new ×××Exception("异常产生的原因");

 我们用算术异常来举例:

注意: 

  1. throw必须写在方法体内部
  2. 抛出的对象必须是Exception或者是Exception的子类对象
  3. 如果抛出的是RunTimeException或RunTimeException的子类,不用处理,直接交给JVM来处理
  4. 如果抛出编译时异常,则必须处理
  5. 异常一旦抛出,后面的代码将不会执行

2、异常的声明——throws

      在Java中,throws关键字用于方法声明时,表示该方法可能会抛出的异常,把处理异常的任务交给方法的调用者。语法如下:

修饰符  返回值类型  方法名  (参数列表) throws  异常类型1,异常类型2···{

}

 我们用文件来举例:

 注意:

  1. throws必须跟在方法的参数列表之后
  2. 声明的异常必须是Exception或Exception的子类
  3. 方法内部如果抛出了多个异常,throws后必须跟多个异常类型,用“ ,”隔开,如果具有父子关系,直接声明父类即可
  4. 如果声明抛出异常的方法时,该异常如果是编译时异常,调用者必须对该异常进行处理,或者继续使用throws抛出

3、异常的捕获——try-catch语句和try-catch-finally语句

      throws对异常并没有真正处理,而是将异常传递给调用者,如果想要真正处理就需要使用try-catch语句。

语法格式:

try{

    //可能出现异常的代码

}catch(要捕获的异常类型 e){

    //try中的语句出现了异常并于catch中的异常类型一致时就会捕获到

    //在捕获完之后跳出try-catch语句,继续执行后续的代码

}catch(异常类型 e){

     //可以增加多个catch语句

}finally{

     //此处代码一定会被执行

}

 

 注意:

  1. try块内抛出异常位置之后的代码将不会执行
  2. 如果抛出异常类型与catch中的异常类型不匹配,即异常不会被捕获,就会继续往外抛,直到JVM收到后中断程序
  3. try中可能会抛出多个不同异常对象,则必须用多个catch来捕获,多个异常捕获也可以写成这样:

catch(异常类型  |   异常类型 e){

     ···

}

     4.如果异常之间具有父子关系,一定是子类异常在前catch,父类异常在后catch

     5.可以通过一个异常捕获所有异常(但不推荐,因为很难分辨),比如Exception可以捕获所有异常 


 try-catch-finally语句

finally相当于程序结束语句,一定会执行,一般用于资源清理的扫尾工作。

如图所示:结果为12,如果finally中存在return语句就会执行finally中的语句,一般不建议在finally中写return语句,编译器会警告。 


4、自定义异常

       在Java中虽然已经内置了丰富的异常类,但是并不能完全表示实际开发中所遇到的异常,这时候就需要我们来实现一个自定义的异常了。

实现一个用户登录功能

实现方式:

  1. 自定义异常类,然后继承Exception或RunTimeException
  2. 实现一个带有String类型参数的构造方法
public class Test {
    public String username="hhh";
    public String password="34438";
    public void log(String username,String password)throws UserNameErrorException,PasswordErrorException{
        if(!this.username.equals(username)){
            throw new UserNameErrorException("用户名错误"+username);
        }
        if(!this.password.equals(password)){
            throw new PasswordErrorException("密码错误"+password);
        }
        System.out.println("登录成功");
    }
    public static void main(String[] args) {
        Test test=new Test();
        try{
            test.log("hhh","34412");
        }catch(UserNameErrorException e){
            e.printStackTrace();
        }catch(PasswordErrorException e){
            e.printStackTrace();
        }
        System.out.println("程序继续执行");
    }
}
 public class PasswordErrorException extends Exception{

      public PasswordErrorException(String mm){

        super(mm);

    }
}
public class UserNameErrorException extends Exception{

 public UserNameErrorException(String s){

        super(s);

    }
}

 以上程序会抛出密码错误的异常。


Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐