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

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

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

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

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

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

二. 异常的分类

 1. 编译时异常 

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

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

2. 运行时异常

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

(1)算数异常

System.out.println(10 / 0);

(2)数组越界异常

int[] arr = {1, 2, 3};
System.out.println(arr[4]);

 (3)空指针异常

int[] arr = null;        
System.out.println(arr.length);

三. 异常处理 

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

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

1. 异常的抛出 throw

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

语法格式:

throw new XXXXException ("这里书写你异常的信息及产生原因");

 使用例子:

int a = 0;
if(a == 0)
{
    throw new ArithmeticException ("a=0是异常");
}

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

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

2. 异常的声明 throws

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

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

}

使用例子:

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

int a = 0;
if(a == 0){
    throw new CloneNotSupportedException ("异常为 a = 0");
}

 

加上throws CloneNotSupportedException后,错误消失

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

我们以如下代码举例

 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 {
//后文会讲
//此处代码一定会被运行到

}

// 如果没有抛出异常,或者异常被捕获处理了,这里的代码也会执行

使用例子: 

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异常类型不匹配
try {
    int a = 10 / 0;
 
}catch (NullPointerException e){
    System.out.println("捕获到了异常");
}
 
System.out.println("后续的代码");
}

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

(2)异常一旦抛出,其后的代码就不会执行
 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 来捕获,但是只能抛出一个异常

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,否则则会报错

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 {
// 此处的语句无论是否发生异常,都会被执行到
}
// 如果没有抛出异常,或者异常被捕获处理了,这里的代码也会执行
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("后续的代码");
}

运行结果: 

四. 自定义异常类

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

 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)

class 自定义异常名称 extends 已有异常类 {

}

具体实现:

 //UserNameException类

class UserNameException extends RuntimeException {
    public UserNameException() {
    }
 
    public UserNameException(String message) {
        super(message);
    }
}

//PasswordException 类

class PasswordException extends Exception {
    public PasswordException() {
    }
 
    public PasswordException(String message) {
        super(message);
    }
}

 //LogIn类

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");
        }
 
    }
}
 

运行结果: 

希望对你有帮助 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值