前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【JAVA SE】异常处理系统整理 简洁易懂!(异常类型、声明异常、抛出异常、捕获异常)

【JAVA SE】异常处理系统整理 简洁易懂!(异常类型、声明异常、抛出异常、捕获异常)

作者头像
用户11292525
发布2024-09-26 11:13:13
1080
发布2024-09-26 11:13:13
举报
文章被收录于专栏:学习

异常处理是JAVA的一种编程概念,用于JAVA程序执行中出现的异常或错误情况。

一. 程序运行出问题的类型

Throwable 异常体系的顶层,其分为 Exception 和 Error 两个子类。

Error 即错误,是JAVA虚拟机无法处理的严重问题。

Exception 即异常,异常产生后,程序员可以通过代码处理,使程序继续运行。 

二. 异常的分类

 1. 编译时异常 

像这样程序还没运行,在编写代码时就报错,就叫编译时异常,也称为受检查异常。

当然,编写代码时的语法错误,是错误!不是异常!

2. 运行时异常

这些在编译时没问题,在程序执行期间发生的异常,就叫运行时异常,也称作非受检查异常。

(1)算数异常
代码语言:javascript
复制
System.out.println(10 / 0);
(2)数组越界异常
代码语言:javascript
复制
int[] arr = {1, 2, 3};
System.out.println(arr[4]);
 (3)空指针异常
代码语言:javascript
复制
int[] arr = null;        
System.out.println(arr.length);

三. 异常处理 

如果方法内出现异常,就会沿着调用栈向上传递,如果向上传递过程中都没有合适的方式处理异常,就会交给JVM处理,程序就会异常终止。

为了避免出现程序运行终止,JAVA提供了以下程序媛可以通过代码处理异常的方式。

1. 异常的抛出 throw

在编写代码时,发现程序出现异常,可以通过throw将异常的信息抛出告知调用者。

语法格式:

代码语言:javascript
复制
throw new XXXXException ("这里书写你异常的信息及产生原因");

 使用例子:

代码语言:javascript
复制
int a = 0;
if(a == 0)
{
    throw new ArithmeticException ("a=0是异常");
}

throw抛出运行时异常时是不需要处理的 ,只是告知调用者。

但是如果时编译时异常,我们则需要处理,而最简单的处理方式是通过throws处理

2. 异常的声明 throws

语法格式:(一般放在方法声明的地方)

代码语言:javascript
复制
修饰符 返回值类型 方法名 (参数列表) throws 异常类型1,异常类型2...{

}

使用例子:

同样的代码,但是我们将异常类型改为编译时异常

代码语言:javascript
复制
int a = 0;
if(a == 0){
    throw new CloneNotSupportedException ("异常为 a = 0");
}
代码语言:javascript
复制
加上throws CloneNotSupportedException后,错误消失

调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用 throws 抛出 

我们以如下代码举例

代码语言:javascript
复制
 public static void main(String[] args) {
        test();
    }
 
    public static void test() throws CloneNotSupportedException{
        int a = 0;
        if(a == 0){
            throw new CloneNotSupportedException("异常为 a = 0");
        }
 
    }

我们将Test问题向上抛出给Main方法处理,但是Main没有继续处理,故报错。 

解决方法有两种:

① 对异常报错的方法再使用throws声明一下

throws 对异常并没有真正处理,而是将异常报告给抛出异常方法的调用者,由调用者处理

如果真正要对异常进行处理,就需要try-catch。

3. 异常的捕获并处理 try-catch

② 使用try-catch捕获并处理该异常

语法格式: try{ //将可能出现异常的代码放在这里 } catch ( 异常类型1 e ){ //如果try中的代码抛出异常了,且try的异常类型与catch括号中的异常类型一致,或者catch括号中的异常try异常类型的父类,就会被catch捕捉到,运行这个大括号里的代码 //在catch里对异常进行正常处理,处理完成后,就会跳出try-catch结构,继续执行后续代码 } catch ( 异常类型2 e ){ //多重catch保险,总有一个try异常能找到属于自己的catch~ //异常处理ing } finally { //后文会讲 //此处代码一定会被运行到 } // 如果没有抛出异常,或者异常被捕获处理了,这里的代码也会执行

使用例子: 

代码语言:javascript
复制
public static void main(String[] args){
 
        try {
            int a = 10 / 0;
        }catch (ArithmeticException e){
            System.out.println("捕获到了异常");
        }
 
 
        System.out.println("后续的代码");
 
    }

try异常类型与catch一致,异常成功捕获,由程序员处理,退出代码为0

注意事项
(1)try异常类型与catch异常类型不匹配
代码语言:javascript
复制
try {
    int a = 10 / 0;
 
}catch (NullPointerException e){
    System.out.println("捕获到了异常");
}
 
System.out.println("后续的代码");
}

导致结果:异常捕获失败,也就不会被处理,继续往外抛,直到JVM收到中断程序,退出代码为1

(2)异常一旦抛出,其后的代码就不会执行
代码语言:javascript
复制
 public static void main(String[] args){

        try {
            int a = 10 / 0; //此处出现异常
            System.out.println("66666666"); //之后的代码便不会被执行

        }catch (ArithmeticException e){
            System.out.println("捕获到了异常");
        }


        System.out.println("后续的代码");

    }

运行结果: 

(3)多个 catch 来捕获,但是只能抛出一个异常

try 中可能会抛出多个不同的异常对象,则必须用多个 catch 来捕获,但是只能抛出一个异常

代码语言:javascript
复制
public static void main(String[] args){

        try {
            int a = 10 / 0;


        }catch (NullPointerException e){
            System.out.println("捕获到了异常111");
        }catch (ArithmeticException e){
            System.out.println("捕获到了异常222");
        }


        System.out.println("后续的代码");
    }

运行结果:

(4)子类异常在前catch,父类异常在后catch

如果异常之间具有父子关系,一定是子类异常在前catch,父类异常在后catch,否则则会报错

代码语言:javascript
复制
public static void main(String[] args){
 
        try {
            int a = 10 / 0;
 
 
        }catch (Exception e){
            System.out.println("捕获到了异常111");
        }catch (NullPointerException e){
            System.out.println("捕获到了异常222");
        }
 
 
        System.out.println("后续的代码");
}

 Exception 是所有异常的父类,所以报错

4. 异常的扫尾处理 finally

在程序正常或者异常退出时,必须要对资源进行回收,而 finally 中的代码一定会执行的,一般在 finally 中进行一些资源清理的扫尾工作

语法格式: try { // 可能会发生异常的代码 } catch ( 异常类型 e ){ // 对捕获到的异常进行处理 } finally { // 此处的语句无论是否发生异常,都会被执行到 } // 如果没有抛出异常,或者异常被捕获处理了,这里的代码也会执行

代码语言:javascript
复制
public static void main(String[] args) {
 
            try {
                int a = 10 / 0;
            } catch (ArithmeticException e) {
                System.out.println("捕获到了异常");
            } finally {
                System.out.println("finally代码");
            }
 
            System.out.println("后续的代码");
}

运行结果:

四. 自定义异常类

假设我们有一个用户登录账号密码的项目业务,处理用户名错误密码错误的时候可能你会这样写代码

代码语言:javascript
复制
 public class Login{
        private String UserName = "jack256";
        private String Password = "123456";
        public void loginInfo (String username,String password){
            if(!this.UserName.equals(username)){
                System.out.println("用户名错误");
            }
            if(!this.Password.equals(password)){
                System.out.println("密码错误");
            }
            System.out.println("登录成功");
        }
    }
    public void main(String[] args) {
        Login login = new Login();
        login.loginInfo("jack256","123456");
    }

但是专业一点,处理用户名错误密码错误我们也可以抛出两种异常,我们可以基于已有的异常类(如 Exception 或者 RunTimeException)进行扩展 ( 继承 ), 自定义创建和我们业务相关的异常类。

  • 继承自 Exception 的异常默认是受查异常
  • 继承自 RuntimeException 的异常默认是非受查异常

语法格式: (自定义异常类,继承自Exception 或者 RunTimeException)

代码语言:javascript
复制
class 自定义异常名称 extends 已有异常类 {

}

具体实现:

 //UserNameException类

代码语言:javascript
复制
class UserNameException extends RuntimeException {
    public UserNameException() {
    }
 
    public UserNameException(String message) {
        super(message);
    }
}

//PasswordException 类

代码语言:javascript
复制
class PasswordException extends Exception {
    public PasswordException() {
    }
 
    public PasswordException(String message) {
        super(message);
    }
}

 //LogIn类

代码语言:javascript
复制
public class LogIn {
    private String userName = "admin";
    private String password = "123456";
    public  void loginInfo(String userName, String password) throws UserNameException,PasswordException{
        if (!this.userName.equals(userName)) {
            //System.out.println("名字错误");
            throw new UserNameException("用户名错误");
        }
        if (!this.password.equals(password)) {
            //System.out.println("密码错误");
            throw new PasswordException("密码错误");
        }
        System.out.println("登陆成功");
    }
 
    public static void main(String[] args) {
        LogIn logIn = new LogIn();
 
        try{
            logIn.loginInfo("admin1", "123456");
        } catch (PasswordException e) {
            e.printStackTrace();
            System.out.println("PasswordException");
        }catch (UserNameException e) {
            e.printStackTrace();
            System.out.println("UserNameException");
        }
 
    }
}

运行结果:

希望对你有帮助 

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-09-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 程序运行出问题的类型
  • 二. 异常的分类
    •  1. 编译时异常 
      • 2. 运行时异常
        • (1)算数异常
        • (2)数组越界异常
        •  (3)空指针异常
    • 三. 异常处理 
      • 1. 异常的抛出 throw
        • 2. 异常的声明 throws
          • 3. 异常的捕获并处理 try-catch
            • 注意事项
          • 4. 异常的扫尾处理 finally
          • 四. 自定义异常类
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档