[JavaSE]异常体系

本文围绕Java异常展开,介绍了异常的理解,指出异常是程序运行出错时给调用者的机制,可根据问题严重程度处理。还阐述了异常体系,包括类继承关系、异常处理方式(try-catch-finally、throw/throws),以及自定义异常的方法,继承自Exception或RuntimeException。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1异常

         1.1异常的理解

         1.2调用栈 e.printStackTrace();

2异常体系

2.1异常的类继承关系:

2.2异常处理(throw/throws)

2.3自定义异常


1异常

1.1异常的理解

我们编写代码的时候,例如打印一个数字除以0或者给定数组长度不够打印需要的数组下标等等问题

一旦出现了异常,程序就会终止。

异常就是程序在运行时出现错误提供给调用者(程序猿)的一种机制

  • 比较严重的问题(例如和算钱相关的场景), 应该让程序直接崩溃, 防止造成更严重的后果
  • 不太严重的问题(大多数场景), 可以记录错误日志, 并通过监控报警程序及时通知程序猿
  • 可能会恢复的问题(和网络相关的场景), 可以尝试进行重试.

在我们当前的代码中采取的是经过简化的第二种方式. 我们记录的错误日志是出现异常的方法调用信息, 能很快
速的让我们找到出现异常的位置. 以后在实际工作中我们会采取更完备的方式来记录异常信息.

1.2调用栈 e.printStackTrace();

方法之间是存在相互调用关系的, 这种调用关系我们可以用 "调用栈" 来描述. 在 JVM 中有一块内存空间称为 "
拟机栈
" 专门存储方法之间的调用关系. 当代码中出现异常的时候, 我们就可以使用  e.printStackTrace(); 的
方式查看出现异常代码的调用栈.

2异常体系

定义:当程序出现错误时能够最大化的减少损失的一种保护手段

Java中异常也是类

2.1异常的类继承关系:

只有Throwable以及子类能够进行异常捕获处理

异常

如果一段代码可能抛出 受查异常, 那么必须显式进行处理. 

  • 受查异常:除了非受查异常的所有异常类都属于受查异常。--------强制用户进行异常处理。
  • 非受查异常:Error/RuntimeException及其子类。-----------------------不强制用户进行异常处理。

2.2异常处理

出现异常时,尽量使得代码能够继续被执行

异常处理的格式:

try
    [catch...]
    [catch...]
    ...
    [finally]
try..[1..N]catch..
try..finally..
try..[1..N]catch..finally
  • try 代码块中放的是可能出现异常的代码
  • catch 代码块中放的是出现异常后的处理行为, catch 进行类型匹配的时候, 不光会匹配相同类型的异常对象, 也会捕捉目标异常类型的子类对象.
  • finally 代码块中的代码用于处理善后工作,无论是否存在异常, finally 中的代码一定(除了退出jvm-下面有例子)都会执行到. 保证最终一定会执行到 Scanner 的 close 方法.
  • 其中 catch 和 finally 都可以根据情况选择加或者不加

 一旦 try 中出现异常, 那么 try 代码块中的程序就不会继续执行, 而是交给 catch 中的代码来执行

catch 执行完毕会继续往下执行

2.2.1throw/throws:

throws:用在方法声明上,明确表示该方法可能会产生异常。当异常产生时,将异常对象扔回给调用者

throw:用在方法中,表示人为进行异常对象的产生-------------------------一般与自定义异常搭配使用

class Test {
    public static void main(String[] args) {
        System.out.println(test());
    }
        public static int test () {
            try {
                System.out.println(10 / 2);
                return 0;
            } catch (ArithmeticException e) {
                return 1;
            } finally {
                return 2;
            }
        }
    }
输出:
5
2

什么时候finally的代码不会被执行?----只有一种情况,退出JVM

class Test {
    public static void main(String[] args) {
        System.out.println(test());
    }
        public static int test () {
            try {
                System.out.println(10 / 2);
                System.exit(0);//系统退出
            } catch (ArithmeticException e) {
                return 1;
            } finally {
                return 2;}
        }
    }

数组越界异常或者类型转换异常都可以用catch(Exception e)来处理 

class Test{
    public static void main(String[] args) {
        System.out.println("1.数学计算开始前");
        try {
            int a=Integer.parseInt(args[0]);
            int b=Integer.parseInt(args[1]);
            System.out.println("2.数学计算开始"+(a/b));
        } catch (Exception e) {
            System.out.println("异常被正确的处理了");
        }
        finally{
            System.out.println("一定会执行此代码");
        }
        System.out.println("3.数学计算结束");
    }
}
输出结果:
1.数学计算开始前
异常被正确的处理了
一定会执行此代码
3.数学计算结束

堆栈溢出错误Error可以采用catch(Throwable e)/catch(Error e)来捕获异常

class Test{
    public static void main(String[] args) {
        System.out.println("1.数学计算开始前");
        try {
            System.out.println("2.数学计算开始");
            fun();
        } catch (Error e) {
            System.out.println("异常被正确的处理了");
        }
        finally{
            System.out.println("一定会执行此代码");
        }
        System.out.println("3.数学计算结束");
        }
    public static void fun(){
        fun();//递归调用
    }
}
输出结果:
1.数学计算开始前
2.数学计算开始
异常被正确的处理了
一定会执行此代码
3.数学计算结束
  • throws:用在方法声明上,明确表示该方法可能会产生异常。当异常产生时,将异常对象扔回给调用者
public class Test{
public static void main(String args[]){
System.out.println(fun(5,0));//报错
}
public static int fun(int a,int b)throws Exception{
return a/b;
}
  • throw:用在方法中,表示人为进行异常对象的产生-------------------------一般与自定义异常搭配使用
public class Test {
    public static void main(String args[]) {
        fun();
    }
    public static void fun() {
        throw new RuntimeException("自定义异常!");
    }
}

2.3自定义异常:

extends RuntimeException or Exception-----------一般用在架构设计时

假设用户登录时,设置用户名和密码

package se.SE.practice;
public class Test {
    private static String userNamename="admin";
    private static String passWord="123456";
    public static void main(String[] args) {
      login("admin","123456");
        }
        public static void login(String userNamename,String passWord){
        if(!Test.userNamename.equals(userNamename)){
            //处理用户名错误
        }
        if(!Test.passWord.equals(passWord)){
            //处理密码错误
        }
        System.out.println("登录成功!");
    }
}

处理用户名异常和密码异常:

基于已有的异常类(Exception类)进行扩展

查看Exception源码

 public Exception(String message) {
        super(message);
    }

    /**
     * Constructs a new exception with the specified detail message and
     * cause.  <p>Note that the detail message associated with
     * {@code cause} is <i>not</i> automatically incorporated in
     * this exception's detail message.
     *
     * @param  message the detail message (which is saved for later retrieval
     *         by the {@link #getMessage()} method).
     * @param  cause the cause (which is saved for later retrieval by the
     *         {@link #getCause()} method).  (A {@code null} value is
     *         permitted, and indicates that the cause is nonexistent or
     *         unknown.)
     * @since  1.4
     */

增加UserError和PassWordError 类继承Exception类

package se.SE.practice;
class UserError extends Exception{
    public UserError(String message){
        super(message);
    }
}
class PassWordError extends Exception{
    public PassWordError(String message){
        super(message);
    }
}
public class Test {
    private static String userNamename="admin";
    private static String passWord="123456";
    public static void main(String[] args) {
        try{
        login("admin","123456");
        }catch(UserError userError){
        userError.printStackTrace();
        }catch (PassWordError passWordError){
         passWordError.printStackTrace();
        }
    }
        public static void login(String userNamename,String passWord)throws UserError,PassWordError{
        if(!Test.userNamename.equals(userNamename)){
            //处理用户名错误
            throw new UserError("用户名错误");
        }
        if(!Test.passWord.equals(passWord)){
            //处理密码错误
            throw new PassWordError("密码错误");
        }
        System.out.println("登录成功!");
    }
}
//输出:登录成功!
  • 自定义异常通常会继承自 Exception 或者 RuntimeException
  • 继承自 Exception 的异常默认是受查异常
  • 继承自 RuntimeException 的异常默认是非受查异常. 
class AddException extends RuntimeException{
    public AddException(String msg){
        super(msg);
    }
}
public class Test {
    public static void main(String args[]) {
        int a=100;
        int b=100;
        int c=a+b;
        if(c==200){
            throw new AddException("此时总数c不可以等于200");
        }
    }

}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值