Java中基于Exception类的异常以及异常处理

简介: 你真的理解异常吗?

@TOC

前言

异常和break有一点点类似,都可以让程序停止运行。异常的发生和人生病是一个道理,处理异常就是看病过程的一种抽象形式,异常处理保证了程序的健壮性,在以后的开发过程中有着举足轻重的作用。当我深入了解异常,发现原来每一种异常都是一个一个进行封装过的类,他们也存在着继承关系。其实,异常也是面向对象特性的一种体现!

一.异常分类

异常(Exception):因编程错误或者偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。
异常分为==运行异常==和==编译异常==

在这里插入图片描述

可以看到,==异常体系其实是一个继承关系==,常见的各种异常都是父类Exception的实现子类,而类所具有的特征Exception类也同样具有,所以我们可以通过实例化异常类的方式来设计异常

二.常见运行异常与编译异常

编译异常:(程序员写代码过程中提示出来的异常)
==SQLException== 操作数据库时,查询表可能发生异常
==IOException== 操作文件时,发生的异常
==FileNotFoundException== 当操作一个不存在的文件时,发生异常
==ClassNotFoundException== 加载类,而该类不存在时,异常
==EOFException== 操作文件,到文件末尾,发生异常
==IllegalArguementException== 参数异常
运行异常:(程序运行时报错显示的异常)
==NullPointerException==空指针异常
==ArithmeticException==数学运算异常
==ArraylndexOutOfBoundsException==数组下标越界异常
==ClassCastException==类型转换异常
==NumberFormatException==数字格式不正确异常[]

三.异常处理

我们都知道,当程序遇到异常时会终止,在大项目的开发中,很难做到不犯任何错误。设想:如果以后开发的大项目出了一点错误就不能运行,那程序的健壮性太差!这就好比一个男人经受一点风吹雨打就卧床不起,太不应该。以下是几种常见的处理异常的方式,使用时选择其中一种就可!

1.try-catch-finally(🚩)

所以Java设计者们设计了==异常处理机制==,这就好比在给程序打补丁,兜底。
语法:

try {
 可能发生异常的代码...
   }catch(异常) {  //捕获到异常
 //处理
  }finally{
//始终要执行的代码
  }

==注意事项:==

🟢当异常发生时系统将异常封装成Exception对象e,传递给catch
🟢得到异常对象后,程序员,自己处理
🟢如果没有发生异常catch代码块不执行
🟢使不管try代码块是否有异常发生,始终要执行finally(所以,通常将释放资源的代码,放在finally部分)
 public static void main(String[] args) {
        try {
            String a = "彭于晏";
            int b = Integer.parseInt(a);  //这里会出现异常
        } catch (Exception e) {
//            e.printStackTrace();
            System.out.println("异常信息:"+e.getMessage());
        }finally{
            System.out.println("finally代码块被执行");
        }
        System.out.println("程序继续~~~");
    }

▶️运行结果:
在这里插入图片描述
我们看到,在程序出现异常的情况下依然完整执行,并且给出了异常内容,这就是机制的妙处所在

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

例如:
在对输入的参数转换为整数并进行除法运算的过程中,会出现很多异常,要根据不同的输入,输出对应的异常,这个需求就体现多个catch语句的好处

public class Play {
    public static void main(String[] args) {
            try{
                Scanner scanner=new Scanner(System.in);
                String str1=scanner.next();
                String str2=scanner.next();
                int n1 = Integer.parseInt(str1);
                int n2 = Integer.parseInt(str2);
                double res=cal(n1,n2);//该方法可能抛出ArithmeticException
                System.out.println("计算结果是:"+res);
            }catch (NumberFormatException e) {
                System.out.println("输入参数格式不正确,重新输入");
            }catch(ArithmeticException e){
                System.out.println("出现了除0的异常~");
            }catch(Exception e){            //这个必须写在子类异常后
                System.out.println("出现了异常~");
            }
        }
        public static double cal(int n1, int n2) {
            return n1 / n2;
        }
}

▶️运行结果:
==ArithmeticException==异常
在这里插入图片描述
==NumberFormatException==异常在这里插入图片描述
==根据不同用户的输入,抛出相应的异常这就是try-catch机制的一个重要作用!==

**try-catch-finally执行顺序:
1.当未出现异常时:执行try块中的所有语句,不执行catch块中的语句,如果有finally,最后要执行finally块中的语句
2.出现异常时:try块中的异常发生后,try块中剩下的语句不再执行,将执行catch块中的语句,同理如果有finally,最后要执行finally块里的语句**

2.throws(🚩)

==throws(抛出)==:在代码中理解成一种抛出难题的行为,它的作用是通过把异常抛给别的类或者方法让当前的部分不受该异常的影响
在这里插入图片描述
==throws注意事项:==
🟢存在继承关系的两个类,子类重写父类方法时,所抛出的异常类型要么和父类抛出异常类型一致,要么为父类抛出的异常类型的子类型
例如:

class Father{
    public void f1() throws Exception{...}
}
class Son extends Father{
    @Override
    public void f1() throws RuntimeException {...}   //或者抛出Exception
}

🟢调用存在异常的方法时要处理他的异常,否则会报错,若是运行异常可以不用显式处理
例如:

class A{
    public static void f4() throws FileNotFoundException{
       try {   
            f3();
       } catch (FileNotFoundException e) {
            e.printStackTrace();
    }
}
    public static void f3() throws FileNotFoundException {   //抛出一个编译异常
        FileInputStream fis=new FileInputStream("xxx");
    }
}

处理的方式可以是try-catch也可以是throws
🟢可以直接访问同类中抛出运行异常的方法,因为==运行异常会被java默认处理==
例如:

class B{
    public static void f5(){
        f6();
    }
    public static void f6() throws ArithmeticException{}
}

3.try-finally

这个用法相当于没有捕获异常,程序会崩掉

try{
   可能出现异常的代码
  }finally{
  总是执行的代码
 }

四.自定义设计异常

我们可以通过继承Exception类的方式来自定义异常,一般情况下,我们自定义异常是继承RuntimeException(运行异常)
即把自定义异常做成运行时异常,好处是我们可以使用Java默认的处理机制!!!

例如:
自定义一个异常类通过实例化它,向构造器中传入自己定义的字符来初始化,达到程序员自定义输出异常内容的目的

public class CustomException {
    public static void main(String[] args) {
        //要求输入一个年龄在18-120,否则抛出一个异常
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入年龄:");
        double age= scanner.nextInt();
        if(!(age>=18&&age<=120)){  
            throw new AgeException("您输入的年龄有误!");
        }
        System.out.println("你的年龄符合~");
    }
}
//自定义一个异常
class AgeException extends RuntimeException{   //继承运行异常 便于处理
    public AgeException(String message) { //构造器
        super(message);
    }
}

▶️运行结果:
在这里插入图片描述

相关文章
|
4天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
28 3
|
1天前
|
Java 数据库连接
深入理解Java异常处理机制
【4月更文挑战第24天】本文将探讨Java中的异常处理机制,包括异常的概念、分类、捕获和抛出等方面。通过深入了解异常处理机制,可以帮助我们编写更加健壮的程序,提高代码的可读性和可维护性。
|
1天前
|
Java 编译器 程序员
【Java基础】细说异常处理
【Java基础】细说异常处理
5 0
|
1天前
|
安全 Java 程序员
|
1天前
|
存储 Java 程序员
JavaSE&Java的异常
JavaSE&Java的异常
11 0
|
2天前
|
Java
Java Class类
Java Class类
8 0
|
8天前
|
Java 编译器
Java Character 类
4月更文挑战第13天
|
9天前
|
存储 Java
Java基础教程(7)-Java中的面向对象和类
【4月更文挑战第7天】Java是面向对象编程(OOP)语言,强调将事务抽象成对象。面向对象与面向过程的区别在于,前者通过对象间的交互解决问题,后者按步骤顺序执行。类是对象的模板,对象是类的实例。创建类使用`class`关键字,对象通过`new`运算符动态分配内存。方法包括构造函数和一般方法,构造函数用于对象初始化,一般方法处理逻辑。方法可以有0个或多个参数,可变参数用`类型...`定义。`this`关键字用于访问当前对象的属性。
|
13天前
|
Java Shell
Java 21颠覆传统:未命名类与实例Main方法的编码变革
Java 21颠覆传统:未命名类与实例Main方法的编码变革
13 0
|
13天前
|
Java
Java 15 神秘登场:隐藏类解析未知领域
Java 15 神秘登场:隐藏类解析未知领域
17 0