异常

程序执行中发生的不正常情况(语句错误/逻辑错误 不是异常)

Error编译时发生

Java虚拟机无法解决的严重问题,改代码解决。

Exception运行时发生

其他因变成错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码处理
需要在编写程序时就考虑到错误检测,错误信息提示,错误处理
有的错误只有在运行时发生,比如:除数为0,数组下标越界

异常体结构

image.png

空指针异常

  1. import org.junit.Test;
  2. public class Main {
  3. //空指针异常
  4. @Test
  5. public void test1(){
  6. int[] arr = null;
  7. System.out.println(arr[0]);
  8. }
  9. }

image.png

数组角标越界

import org.junit.Test;

public class Main {
    //数组角标越界
    @Test
    public void test1(){
        int[] arr = new int[10];
        System.out.println(arr[10]);
    }
}

image.png

import org.junit.Test;

public class Main {
    //字符串角标越界
    @Test
    public void test1(){
        String str = "abc";
        System.out.println(str.charAt(4));
    }
}

//java.lang.StringIndexOutOfBoundsException: String index out of range: 4

java.lang.StringIndexOutOfBoundsException: String index out of range: 4

类型转换异常

import org.junit.Test;

import java.util.Date;

public class Main {
    //类型转换异常ClassCastException
    @Test
    public void test1(){
        Object obj = new Date();
        String str = (String)obj;
    }
}

image.png

数字格式化异常

public class Main {
    //类型转换异常NumberFormatException
    @Test
    public void test1(){
        String str = "123";
        str = "abc";
        int num = Integer.parseInt(str);
    }
}

image.png

输入异常

public class Main {
    public static void main(String[] args) {
        //类型转换异常InputMismatchException
        Scanner scanner = new Scanner(System.in);
        int score = scanner.nextInt();
        System.out.println(score);
    }
}

image.png

算数异常

//算数异常ArithmeticException
        int a =10;
        int b = 0;
        System.out.println(a/b);

image.png

异常的处理机制—抓抛模型

“抛”:程序正在执行的过程中,一但出现异常,就会在异常代码处生成一个对应异常类的对象,并将此对象抛出,一旦抛出对象,其后代码不再执行
“抓”:异常处理方式

try-catch-finally

try{
//可能出现异常的代码
}catch(异常类型1 变量名1){
//异常处理的方式1
}catch(异常类型2 变量名2){
//异常处理的方式2
}catch(异常类型3 变量名3){
//异常处理的方式3
}
……
finally{
//一定会执行的代码
}
**

  1. finally 可选择使用
  2. 使用try将可能出现异常代码包装起来,在执行过程中一旦出现异常就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配 ```java public class Main { public static void main(String[] args) {
     String str = "123";
     str = "abc";
     try{
         int num = Integer.parseInt(str); //可能出现的异常
         System.out.println("Hello1");
     }catch (NumberFormatException e){
         System.out.println("出现数字转换异常了,不要着急...");
     }
     System.out.println("HEllo2");
    
    } }

结果: 出现数字转换异常了,不要着急… HEllo2

![image.png](https://cdn.nlark.com/yuque/0/2020/png/2211273/1602667023689-f0d6951c-b98d-48a6-ace7-6ff272f63aed.png#align=left&display=inline&height=313&margin=%5Bobject%20Object%5D&name=image.png&originHeight=411&originWidth=666&size=32283&status=done&style=none&width=508)
```java
public class Main {
    public static void main(String[] args) {
        String str = "123";
        str = "abc";
        try{
            int num = Integer.parseInt(str); //可能出现的异常
            System.out.println("Hello1");
        }catch (NullPointerException e){  //开错药了,没吃,str根本没进去
            System.out.println("出现数字转换异常了,不要着急...");
        }
        System.out.println("HEllo2");
    }
}
Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"

catch 内的 异常处理 编写错误,则异常根本进不去catch,相当于没处理
image.png

  1. 一旦try中的异常对象匹配到某一个catch,就进入catch中进行异常的处理,一旦处理完成,就跳出当前try-catch结构(没写finally情况),继续执行其后代码。 ```java public class Main { public static void main(String[] args) {
     String str = "123";
     str = "abc";
     try{
         int num = Integer.parseInt(str); //可能出现的异常
         System.out.println("Hello1");
     }catch (NullPointerException e){  //开错药了,没吃,str根本没进去
         System.out.println("出现空指针异常了,不要着急...");
     }catch(NumberFormatException e){
         System.out.println("出现数据转换异常");
     }
     System.out.println("HEllo2");
    
    } }

结果 出现数据转换异常 HEllo2 ```

  1. catch中的异常类型如果没有子父类关系,则谁声明在上下无所谓

若满足子父类关系,则子在父上,否则报错
image.png
image.png

异常处理方式常调方法

getMessage()

System.out.println(e.getMessage);

printStackTrace()

e.printStackTrace();

体会

  1. 使用try处理编译异常,使得程序在编译时就不再报错,但是运行时仍可能报错。相当于在我们使用try将一个编译时可能出现的异常延迟到运行时出现
  2. 开发时,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally

针对编译时异常,我们说一定要考虑异常的处理

throws+异常处理

  1. 写在方法的声明处,指明此方法执行时,可能会抛出的异常类型

一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后的异常类 型时就会被抛出。异常代码后续的代码就不再执行

  1. try-catch-finally:真正的将异常处理掉

throws的方式只是将异常抛给了调用者,并没有真正将异常处理掉