【JAVA异常处理 | try-catch、throw、throws】

异常

一般异常代码:

public class Exception01 {
    
    
    public static void main(String[] args) {
    
    
        int n1 = 10;
        int n2 = 0;
        // n1 / n2 => 10 / 0
        int res = n1/n2;
        System.out.println("程序继续运行……");
    }
}

设置了异常捕获(try-catch):

public class Exception01 {
    
    
    public static void main(String[] args) {
    
    
        try{
    
    
            int n1 = 10;
            int n2 = 0;
            // n1 / n2 => 10 / 0
            int res = n1/n2;
        } catch (Exception e){
    
    
            // TODO:handle exception
            //e.printStackTrace();//打印异常堆栈,即将异常出错的代码和信息输出
            System.out.println("异常信息=" + e.getMessage());
        }
        System.out.println("程序继续运行……");
    }
}

异常介绍

基本概念

Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法
错误和逻辑错误不是异常)

异常事件可分为两类(Error,Exception)

  1. Error(错误):Java虛拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如: StackOverflow Error栈溢出]和ooM( out of
    memory),Error是严重错误,程序会崩溃。
  2. Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指访问,试图读取不存在的文件,网络连接中
    断等等, Exception分为两大类:运行时异常[程序运行时,发生的异常]和编译时异常[编译时,编译器检查出的异常]。

类关系图:

image-20211007080111311

常见运行时异常

  1. NullPointerException空指针异常

    String name = null;
    System.out.println(name.length());
    
  2. ArithmeticException数学运算异常

    int n1 = 10;
    int n2 = 0;
    int res = n1/n2;
    
  3. ArrayIndexOutOfBoundsException数组下标越界异常

    int[] arr = {
          
          1, 2, 4};
    for (int i = 0; i <= arr.length; i++) {
          
          
        System.out.println(arr[i]);
    }
    
  4. ClassCastException类型转换异常

    public class ClassCastException_ {
          
          
        public static void main(String[] args) {
          
          
            A b = new B();//向上转型
            B b2 = (B)b;//向下转型,OK的
            C c2 = (C)b;//这里会抛出ClassCastException类型转换异常
        }
    }
    
    class A {
          
          }
    class B extends A {
          
          }
    class C extends B {
          
          }
    
  5. NumberFormatException数字格式不正确异常

    String name = "Jack";
    //将 String 解析成 int
    int num = Integer.parseInt(name);
    

常见编译时异常

  1. SQLException
  2. IOException
  3. FileNotFoundException
  4. ClassNotFoundException
  5. EOFException
  6. IlldgalArgumentException

异常处理

基本介绍

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

异常处理的方式

  1. try-catch-finally
    程序员在代码中捕获发生的异常,自行处理
  2. throws
    将发生的异常抛出,交给调用者来处理,最顶级的处理者是JVM

try-catch-finally

try{
    
    
    //代码/可能有异常
} catch (Exception e) {
    
    
    //捕获异常
    //1.当异常发生时
    //2.系统将异常封装成Exception对象e,,传递给catch
    //3.得到异常对象后,程序员自己处理
} finally {
    
    
    //没有finally语法也是可以通过的
    //不管有没有异常,finally一定要执行
}

throws

image-20211007083738808

异常默认使用throws。

try-finally

直接使用try-finally进行配合,相当于没有捕获异常,因此程序会直接崩溃。应用场景,就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑。

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

Try机制

TryCatchDetail01.java

使用ctrl + alt + t快捷键设置try-catch

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7aIbVacn-1644128312071)(.\image\image-20211007084308512.png)]

public class TryCatch01 {
    
    
    public static void main(String[] args) {
    
    

        try {
    
    
            String str = "Jack";
            int a = Integer.parseInt(str);
            System.out.println("数字:" + a);
        } catch (NumberFormatException e) {
    
    
            System.out.println("异常信息 = " + e.getMessage());
        }

        System.out.println("程序继续......");
    }
}

如果希望不管发生什么都执行某段代码,则使用finally。

可以有多个 catch语句,捕获不同的异常进行不同的业务处理),要求父类异常在后,子类异常在前,比如( Exception在后, NullPointerException在前),如果发生异常,只会匹配一个 catch。

TryCatchDetail02.java

public class TryCatchDetail02 {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            Person person = new Person();
            person = null;
            System.out.println(person.getName());//NullPointerException
            int n1 = 10;
            int n2 = 0;
            int res = n1 / n2;//ArithmeticException
        } catch (Exception e) {
    
    
            System.out.println(e.getMessage());
        } finally {
    
    
        }
    }
}

class Person{
    
    
    private String name;

    public String getName() {
    
    
        return name;
    }
}

改进后的多异常处理:

子类异常必须放在前面!!!

public class TryCatchDetail02 {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            Person person = new Person();
            person = null;
            System.out.println(person.getName());//NullPointerException
            int n1 = 10;
            int n2 = 0;
            int res = n1 / n2;//ArithmeticException
        } catch (NullPointerException e) {
    
    
            System.out.println("空指针异常: " + e.getMessage());
        } catch (ArithmeticException e) {
    
    
            System.out.println("算数异常: " + e.getMessage());
        } catch (Exception e) {
    
    
            System.out.println("一般异常: " + e.getMessage());
        } finally {
    
    
        }
    }
}

class Person{
    
    
    private String name;

    public String getName() {
    
    
        return name;
    }
}

TryCatchDetail03.java

public class TryCatchDetail03 {
    
    
    public static void main(String[] args) {
    
    
        try{
    
    
            int n1 = 10;
            int n2 = 0;
            System.out.println(n1 / n2);
        } finally {
    
    
            System.out.println("执行了finally...");
        }

        //不会继续运行,程序运行完finally后直接崩溃
        System.out.println("程序继续运行...");
    }
}

TryCatchExercise01.java

public class TryCatchExercise01 {
    
    
    public static int method(){
    
    
        try{
    
    
            String[] names = new String[3];
            if(names[1].equals("tom")){
    
    //NullPointerException
                System.out.println(names[1]);
            } else{
    
    
                names[3] = "hspedu";
            }
            return 1;
            }
        catch (ArrayIndexOutOfBoundsException e){
    
    
            return 2;
        }
        catch (NullPointerException e){
    
    
            return 3;
        }
        //由于finally必须执行,则一定返回4
        finally{
    
    
            return 4;
        }
    }

    public static void main(String[] args) {
    
    
        System.out.println(method());
    }
}

TryCatchExercise02.java

public class TryCatchExercise02 {
    
    
    public static int method(){
    
    
        int i = 1;
        try{
    
    
            i++;//2
            String[] names = new String[3];
            if(names[1].equals("tom")){
    
    //NullPointerException
                System.out.println(names[1]);
            } else{
    
    
                names[3] = "hspedu";
            }
            return 1;
        }
        catch (ArrayIndexOutOfBoundsException e){
    
    
            return 2;
        }
        catch (NullPointerException e){
    
    
            return ++i;//3
        }
        //由于finally必须执行,则一定返回4
        finally{
    
    
            return ++i;//4
        }
    }

    public static void main(String[] args) {
    
    
        System.out.println(method());//4
    }
}

TryCatchExercise03.java

public class TryCatchExercise03 {
    
    
    public static int method(){
    
    
        int i = 1;//1
        try{
    
    
            i++;//2
            String[] names = new String[3];
            if(names[1].equals("tom")){
    
    //NullPointerException
                System.out.println(names[1]);
            } else{
    
    
                names[3] = "hspedu";
            }
            return 1;
        }
        catch (ArrayIndexOutOfBoundsException e){
    
    
            return 2;
        }
        catch (NullPointerException e){
    
    
            //返回3
            return ++i;//3
        }
        finally{
    
    
            ++i;//4
            System.out.println("i = " + i);//i = 4
        }
    }

    public static void main(String[] args) {
    
    
        System.out.println(method());//3
    }
}

TryCatchExercise04 – 用异常捕获获取输入

public class TryCatchExercise04 {
    
    
    /* 1.创建Scanner
     * 2.使用无限循环去接受一个输入
     * 3.然后将输入的值转化为int
     * 4.如果在转化时抛出异常,则说明输入内容不能转化为int
     * 5.如果没有抛出,则break该循环*/
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        int num = 0;
        while (true) {
    
    
            System.out.println("请输入一个整数:\n");
            try {
    
    
                num = Integer.parseInt(scanner.next());
                break;
            } catch (NumberFormatException e) {
    
    
                System.out.println("输入有误,请重新输入!\n");
            }
        }
        System.out.printf("您的输入为: " + num);
    }
}

Throws机制

如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对异常进行处理。

在方法中使用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。

Throws01.java

public class Throws01 {
    
    
    public static void main(String[] args) {
    
    

    }

    //public void f1() throws Exception 也可以
    public void f1() throws FileNotFoundException, NullPointerException {
    
    
        //创建了一个文件流对象
        //这里的异常是一个FileNotFoundException
        //可以使用try-catch
        //也可以使用throws,抛出异常,让调用fi方法的调用者()处理
        //throws关键字后也可以是列表
        FileInputStream fis = new FileInputStream("dd.txt");
    }
}

ThrowsDetail.java

  1. 对于编译异常,程序中必须处理,比如try-catch或者throws

  2. 对于运行时异常,程序中如果没有处理,默认是throws的方法处理

  3. 子类重写父类的方法时,对抛出异常的规定:子类重写的方法所抛出的异常类型要么和父类抛出的一致,要么为父类抛出异常类型的子类型。

    class Father {
          
          
        public void method() throws RuntimeException{
          
          
        }
    }
    
    class Son extends Father {
          
          
        //子类重写父类的方法时,对抛出异常的规定:
        // 子类重写的方法所抛出的异常类型要么和父类抛出的一致,
        // 要么为父类抛出异常类型的子类型。
        @Override
        public void method() throws NullPointerException {
          
          
    
        }
    }
    

编译异常的处理

image-20211008234206117

解决方法1:使用try-catch处理

解决方法2:throws抛出

image-20211008234445456

运行异常的处理

自定义异常

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

自定义异常步骤

  1. 定义类:自定义异常类名,继承ExpectionRnntimeExpection
  2. 如果继承Expection,属于编译异常
  3. 如果继承RuntimeExpection,属于运行异常(一般继承RuntimeExpection)

CustomException.java

public class CustomExpection {
    
    
    public static void main(String[] args) {
    
    
        int age = 800;
        //要求年龄在18-120之间1,否则抛出一个异常
        if (!(age >= 18 && age <= 120))
        {
    
    
            throw new AgeException("年龄需要在18~120之间!");
        }
        System.out.println("你的年龄范围正确!");
    }
}

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

throw和throws的区别

意义 位置 后面跟的东西
throws 异常处理的一种方式 方法声明处 异常类型
throws 手动生成异常对象的关键字 方法体中 异常对象

猜你喜欢

转载自blog.csdn.net/weixin_46421722/article/details/122797928