java中异常类

news2024/12/22 22:17:33

异常

异常体系继承结构

 Throwable类是 Java 语言中所有错误或异常的超类,只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。
    异常是对象,而对象都采用类来定义。异常的根类是 java.lang.Throwable。关系图如下:

    注意:类名 Error、Exception 和 RuntimeException 有时候容易引起混淆。这三种类都是异常,这里讨论的错误都发生在运行时。
    Throwable 类是所有异常类的根。所有的 Java 异常类都直接或者间接地继承自Throwable。可以通过继承 Exception 或者 Exception 的子类来创建自己的异常类。
    这些异常类可以分为三种主要类型:系统错误、编译时异常和运行时异常。

  • Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获。Exception 又可以分为 Checked Exception (受检查异常,必须处理) 和 Unchecked Exception (不受检查异常,可以不处理)。
  • ErrorError 属于程序无法处理的错误 ,我们没办法通过 catch 来进行捕获不建议通过catch捕获 。例如 Java 虚拟机运行错误(Virtual MachineError)、虚拟机内存不够错误(OutOfMemoryError)、类定义错误(NoClassDefFoundError)等 。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止

1.系统错误(Error)

  • 系统錯误(system error) 是由 Java 虚拟机抛出的,用 Error 类表示。Error 类描述的是内部系统错误。这样的错误很少发生。如果发生,除了通知用户以及尽量稳妥地终止程序外,几乎什么也不能做。

OutOfMemoryError :内存耗尽 ;
NoClassDefFoundError :无法加载某个Class ;
StackOverflowError :栈溢出。

2.编译时异常(Exception)

  • 编译时异常:Exception及其子类(除了RuntimeException),在编译时期抛出的异常,在编译期间检查程序是否可能会出现问题,如果可能会有,则预先防范:捕获 声明。

Exception 则是编译时异常,它可以被捕获并处理。
某些异常是应用程序逻辑处理的一部分,应该捕获并处理。例如:

NumberFormatException :数值类型的格式错误;
FileNotFoundException :未找到文件;
SocketException :读取网络失败。
还有一些异常是程序逻辑编写不对造成的,应该修复程序本身。例如:

NullPointerException :对某个 null 的对象调用方法或字段;
IndexOutOfBoundsException :数组索引越界。

3.运行时异常(RuntimeException)


运行时异常(runtime exception) 是用 RuntimeException 类表示的,它描述的是程序设计错误,例如,错误的类型转换、访问一个越界数组或数值错误。运行时异常通常是由 Java 虚拟机抛出的。
RuntimeException是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类,可能在执行方法期间抛出但未被捕获的 RuntimeException 的任何子类都无需在 throws 子句中进行声明,指的就是这些问题不需要提前被预防(本质上也可以的,只不过没必要),因为只有在真正运行的时候才能发现是否发生问题,一旦在运行期间发生了问题,则一般不会修正,程序直接中断

Checked Exception 和 Unchecked Exception 有什么区别?

Checked Exception 即 受检查异常 ,Java 代码在编译过程中,如果受检查异常没有被 catch或者throws 关键字处理的话,就没办法通过编译。

比如下面这段 IO 操作的代码:

 

除了RuntimeException及其子类以外,其他的Exception类及其子类都属于受检查异常 。常见的受检查异常有:IO 相关的异常、ClassNotFoundExceptionSQLException...。

Unchecked Exception不受检查异常 ,Java 代码在编译过程中 ,我们即使不处理不受检查异常也可以正常通过编译。

RuntimeException 及其子类都统称为非受检查异常,常见的有(建议记下来,日常开发中会经常用到):

  • NullPointerException(空指针错误)
  • IllegalArgumentException(参数错误比如方法入参类型错误)
  • NumberFormatException(字符串转换为数字格式错误,IllegalArgumentException的子类)
  • ArrayIndexOutOfBoundsException(数组越界错误)
  • ClassCastException(类型转换错误)
  • ArithmeticException(算术错误)
  • SecurityException (安全错误比如权限不够)
  • UnsupportedOperationException(不支持的操作错误比如重复创建同一用户)

什么异常可以不处理,什么异常一定要处理

 RuntimeException、Error 以及它们的子类都称为免检异(unchecked exception )。所有其他异常(编译时异常)都称为必检异常(checked exception), 意思是指编译器会强制程序员检査并通过 try- catch 块处理它们,或者在方法头进行声明。

    在大多数情况下,免检异常都会反映出程序设计上不可恢复的逻辑错误。例如,如果通过一个引用变量访问一个对象之前并未将一个对象陚值给它,就会抛出 NullPointerException异常;如果访问一个数组的越界元素,就会抛出IndexOutOfBoundsException 异常。这些都是程序中必须纠正的逻辑错误。免检异常可能在程序的任何一个地方出现。为避免过多地使用 try-catch 块,Java 语言不强制要求编写代码捕获或声明免检异常。

Java规定:

必须捕获的异常,包括 Exception 及其子类,但不包括 RuntimeException 及其子类,这种类型的异常称为Checked Exception。
不需要捕获的异常,包括 Error 及其子类, RuntimeException 及其子类。

处理异常方式

2.1 JVM默认处理异常的方式

这种方式就是我们直接一直向上抛出之后最后就是jvm进行处理。
如果程序出现了问题,我们没有做任何处理,最终JVM 会做默认的处理,处理方式有如下两个步骤:
把异常的名称,错误原因及异常出现的位置等信息输出在了控制台
程序停止执行


2.2 try - catch方式处理异常 

  • 定义格式


try {
    可能出现异常的代码; 
} catch(异常类名 变量名) {
     异常的处理代码; 
}


 

  • 执行流程

  1. 程序从 try 里面的代码开始执行
  2. 出现异常,就会跳转到对应的 catch 里面去执行
  3. 执行完毕之后,程序还可以继续往下执行
  • 示例代码

 public class ExceptionDemo01 { 
    public static void main(String[] args) { 
        System.out.println("开始"); method(); 
        System.out.println("结束"); 
    }
    public static void method() { 
        try {
            int[] arr = {1, 2, 3}; 
            System.out.println(arr[3]); 
            System.out.println("这里能够访问到吗"); 
        } catch (ArrayIndexOutOfBoundsException e) { 
            // System.out.println("你访问的数组索引不存在,请回去修改为正确的索引"); 
            e.printStackTrace(); 
        } 
    } 
}

 这种方式处理异常就是直接就在本方法中进行处理,不交给其他调用者进行处理。

 2.3 throws方式处理异常

  • 格式

public void 方法() throws 异常类名 { 

}
 

这种方式处理异常方式就是我自己不处理,交给调用者进行处理,调用者如何处理呢,还是两种方式try catch 或者继续向上抛出交给其他调用者处理,如果一直抛的话,最后就是jvm最后进行处理(默认处理)。

  • 示例代码

/*
    throws 异常类名;
    这个格式是跟在方法的括号后面的
 */
public class ExceptionDemo {
    public static void main(String[] args) {
        System.out.println("开始");
//        method();
        try {
            method2();
        }catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println("结束");
    }

    //编译时异常
    public static void method2() throws ParseException {
        String s = "2048-08-09";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d = sdf.parse(s);
        System.out.println(d);
    }

    //运行时异常
    public static void method() throws ArrayIndexOutOfBoundsException {
        int[] arr = {1, 2, 3};
        System.out.println(arr[3]);
    }

}
 

为什么要抛出异常?什么时候要抛出异常?

 为什么要捕获异常?

编译时程序有可能会出现异常,如果出现异常,程序就会中断,但是你不想程序中断的话,就可以选择
捕获异常,做出处理,让程序可以运行下去。
例子:比如程序中有3行代码,第2行有异常。

如果不处理第1行代码的异常,那么第3行代码就执行不了;
如果处理的第2行代码的异常后,程序就可以继续执行第3行代码。

抛出异常和捕获异常的区别?


抛出异常:如果程序出现了异常,没有办法将具体的异常打印出来,不做任何处理;程序中断。 

捕获异常:如果程序出现了异常,就能够详细的打印是什么原因导致了异常并且能够做出相应的处理,能够显示详细的日志,程序不中断。

编译异常和运行异常的区别?什么时候要抛出异常? 


编译时异常必须要进行处理,两种处理方案:try…catch …或者 throws,如果采用throws 这种方案, 将来谁调用谁处理 ,处理用到try…catch…捕获或者抛出一层层往上抛,最终抛给虚拟机
运行时异常可以不处理,出现问题后,需要我们回来修改代码

throw和throws的区别

throws

  • 用在方法声明后面,跟的是异常类名
  • 表示抛出异常,由该方法的调用者来处理
  • 表示出现异常的一种可能性,并不一定会发生这些异常

throw

  • 用在方法体内,跟的是异常对象名
  • 表示抛出异常,由方法体内的语句处理
  • 执行 throw 一定抛出了某种异常

throw就是主动抛出一个异常 , 要很确信这个代码一定会发生异常,我们才会直接主动抛出去,用在方法体中。对于throws用在方法上 这是这个方法可能会抛出异常,也可能不会抛出异常,如果抛出了异常则交给我们调用者进行处理。

总结:

  1. throw 是语句抛出一个异常;throws 是方法抛出一个异常;
  2. throw语法:throw <异常对象>
  3. throws语法:[<修饰符>]<返回值类型><方法名>([<参数列表>])[throws<异常类>]

public class ThrowTest {
    public static void main(String[] args) {
        try {
            // 调用声明抛出 Checked 异常的方法,要么显式捕获该异常
            // 要么在 main 方法中再次声明抛出
            throwChecked(-3);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        // 调用声明抛出 Runtime 异常的方法既可以显式捕获该异常
        // 也可不理会该异常
        throwRuntime(3);
    }
    
    public static void throwChecked(int a) throws Exception{
        if (a > 0){
            //自行抛出 Exception 异常
            //该代码必须处于 try 块里,或处于带 throws 声明的方法中
            throw new Exception("a 的值大于 0,不符合要求");
        }
    }
    
    public static void throwRuntime(int a){
        if( a > 0) {
            // 自行抛出 RuntimeException 异常,既可以显式捕获该异常
            // 也可完全不理会该异常,把该异常交给该方法调用者处理
            throw new RuntimeException("a 的值大于 0,不符合要求");
        }
    }
}
 

throw使用限制

try 块里,或处于带 throws 声明的方法中

throw 必须是直接实现或者间接继承hrowable类的子类的对象

实现自定义异常类

1、自定义异常类继承Exception类

/**
 * 自定义异常类
 */
public class MyException extends Exception {
    //异常信息
    private String message;

    //构造函数
    public MyException(String message){
        super(message);
        this.message = message;
    }

    //获取异常信息,由于构造函数调用了super(message),不用重写此方法
    //public String getMessage(){
    //    return message;
    //}
}
 

2、在要抛出异常的函数使用throws关键字

/**
 * 在需要抛出异常的地方使用异常类
 */
public class UseMyException {
    private String name;
    private String password;

    public UseMyException(String name,String password){
        this.name = name;
        this.password = password;
    }

    public void throwException(String password) throws MyException{
        if (!this.password.equals(password)){
            throw new MyException("密码不正确!");
        }
    }
}
 

3、测试,使用try-catch处理异常

/**
 * 测试异常
 */
public class TestException {

    @org.junit.Test
    public void test(){
        UseMyException ex = new UseMyException("admin","123");
        try{
            ex.throwException("1234");
        }catch (MyException me){
            System.out.println("MyException:"+me.getMessage());
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1538818.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDEA使用手册

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

真机笔记(1)第一阶段知识讲解

目录 第一阶段讲解&#xff1a; 1.1 机房 1.2 分类&#xff1a; 1.3 机房建设标准 1.3.1 安全性: 1.3.2 供电&#xff1a; 1.3.3 空气调节&#xff1a;&#xff08;恒温恒湿&#xff09; 1.3.4 电磁防护&#xff1a; 2.1 机柜 2.2 分类 2.3 机柜的高度单位 3.1 设备…

postman 用上一个请求的响应体中的字段设置下一个请求的请求参数

文章目录 IntroPostman usagePre-request ScriptTests javascripts API Intro 这一切都是为了增加自动化动作所占的比例&#xff08;减少人手工操作复制粘贴可能会造成的错误&#xff09;。 Postman usage 最常用的&#xff1a;选HTTP方法类型、写URL&#xff0c;在Headers中…

1240. 完全二叉树的权值

给定一棵包含 N 个节点的完全二叉树&#xff0c;树上每个节点都有一个权值&#xff0c;按从上到下、从左到右的顺序依次是 A1,A2,⋅⋅⋅AN&#xff0c;如下图所示&#xff1a; 现在小明要把相同深度的节点的权值加在一起&#xff0c;他想知道哪个深度的节点权值之和最大&#x…

外包干了6天,技术退步明显。。。。

说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入上海某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&a…

【Linux命令】查看内存占用情况(mem, swap)

1. 方法1&#xff08;top&#xff09; # top2.方法2&#xff08;free&#xff09; # free -h3. 方法3&#xff08;swapon&#xff09; # swapon -s

【技巧】ChatGPT Prompt 提示语大全

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 主要来自&#xff1a;https://github.com/f/awesome-chatgpt-prompts ChatGPT SEO提示 Contributed by: StoryChief AI Reference: 7 Powerful ChatGPT Prompts to Create SEO Content Faster 供稿人&#xff1a;…

STM32 CubeMx创建Lwip+FreeRtos时出现ping不通的问题

STM32 CubeMx创建LwipFreeRtos时出现ping不通 1、配置ETH&#xff0c;使用中断 2、配置Lwip&#xff08;使用静态ip&#xff09;&#xff0c;其余什么都不用管 3、配置FreeRtos&#xff08;选择V2版本&#xff09;&#xff0c;其余什么都不用管 4、创建代码 5、查看自动生…

在虚拟机上安装ubuntu

初学者建议选择“清除整个磁盘并安装ubuntu”&#xff0c;下面那个选项留给熟练使用虚拟机后的自己吧&#xff0c;哈哈。需要了解的是&#xff0c;“清除整个磁盘并安装ubuntu”此选项仅仅会清除你这个虚拟机分配的磁盘&#xff0c;不会影响你电脑上的其它虚拟机&#xff0c;哪…

深度学习,CRNN+CTC和Attention OCR你更青睐哪一种?

深度学习在OCR领域的应用已经取得了瞩目的成果&#xff0c;而选择合适的算法对于提升OCR的识别准确率至关重要。在众多算法中&#xff0c;CRNN和Attention OCR犹如两颗璀璨的明珠&#xff0c;备受瞩目。 CRNN&#xff0c;这位结合了卷积神经网络&#xff08;CNN&#xff09;和…

UE5 GameMode C++函数 学习

已经尝试&#xff0c;确实能重启游戏 类描述符加了noplaceable过后即使是Actor也不能放到场景中了&#xff0c;关卡蓝图&#xff0c;GameMode&#xff0c;GameState这些就不能放场景中了 UFUNCTION(exec)

lora-scripts 训练IP形象

CodeWithGPU | 能复现才是好算法CodeWithGPU | GitHub AI算法复现社区&#xff0c;能复现才是好算法https://www.codewithgpu.com/i/Akegarasu/lora-scripts/lora-trainstable-diffusion打造自己的lora模型&#xff08;使用lora-scripts&#xff09;-CSDN博客文章浏览阅读1.1k次…

C/C++在线参考手册的使用技巧

cppreference.com是一个在线的C/C参考手册&#xff0c;是C/C学习者最常用的网站。 网址&#xff1a;cppreference.com 1&#xff0e;搜索 不知道为什么这个网站总是不能正常搜索&#xff0c;实在是太不方便了。 有两个退而求其次的方法&#xff1a; (1)通过搜索引擎指定域名…

【Netty】TCP粘包、拆包、编解码问题

TCP粘包、拆包、编解码问题 UserInfo userInfo1new UserInfo();ByteBuf buf Unpooled.copiedBuffer(userInfo1.toString().getBytes(StandardCharsets.UTF_8));UserInfo userInfo1new UserInfo(); 这行代码创建了一个新的UserInfo对象&#xff0c;并将其引用存储在名为userInf…

基于SpringBoot医院管理系统

采用技术 基于SpringBoot医院管理系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 医生模块 病床信息管理 药房信息管理 护士模块 个人中心管理 …

DS-红黑树(RBTree)

一.红黑树 1.1 红黑树的起源 当对对AVL树做一些结构修改的操作时候&#xff0c;性能较为低下&#xff0c;比如&#xff1a;插入时要维护其绝对平衡&#xff0c;旋转的次数比较多&#xff0c;更差的是在删除时&#xff0c;有可能一直要让旋转持续到根的位置。 因此1972年Rudolf…

循环冗余校验CRC和FPGA实现

一、概念 CRC校验&#xff0c;中文翻译过来是&#xff1a;循环冗余校验&#xff0c;英文全称是&#xff1a;Cyclic Redundancy Check。是一种通过对数据产生固定位数的校验码&#xff0c;以检验数据是否存在错误的技术。 其主要特点是检错能力强、开销小&#xff0c;易于电路实…

设计模式 --4:工厂方法模式

总结 &#xff1a; 个人理解&#xff1a; 工厂方法模式就是在简单工程模式的基础下将工厂类抽象出来。如果不抽象工厂类 &#xff0c;每一次创建一个新的算法&#xff0c;都要修改原来的工厂类&#xff0c;这不符合 开放–封闭原则 将工厂类给抽象出来&#xff0c;让具体的算法…

Node安装,nodejs详细安装步骤

什么是nodejs? 脚本语言需要一个解析器才能运行&#xff0c;JavaScript是脚本语言&#xff0c;在不同的位置有不一样的解析器&#xff0c;如写入html的js语言&#xff0c;浏览器是它的解析器角色。而对于需要独立运行的JS&#xff0c;nodejs就是一个解析器。 每一种解析器都是…

Springboot解决跨域问题方案总结(包括Nginx,Gateway网关等)

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 前言 解决跨域问题方案 1.Spring Boot 中解决跨域 1.1 通过注解跨域 1.2 通…