Java打怪升级宝典:Java中的异常你真的了解吗?

简介: Java打怪升级宝典:Java中的异常你真的了解吗?

文字版

一、异常处理机制的初衷

异常,说白了就是程序出现了某种错误。

因为这种异常处理机制的存在,大大降低了编写和维护可靠程序的门槛。

现代编程语言基本上都有异常处理机制,异常处理机制也成了编程语言的标配。

二、抛出问题

今天的问题是:

1、对比Exception和Error。

2、运行时异常与一般异常有什么区别?

三、解析问题

为了方便理解,这里我画了一个图:

先来看个图:

Exception和Error都是继承了Throwable类,在Java中只有Throwable类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。

Exception和Error两种类型是针对Java平台不同异常情况的分类

Exception是程序正常运行中,可以预料的意外情况,可能并且应该被捕捉,进行相应处理。

Error是指正常情况下,不大可能出现的情况,绝大部分的Error都会导致程序(比如JVM自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如NoClassDefFoundError之类的类型,都是Error的子类。

可检查异常和不检查异常

Exception又分为可检查(checked)异常和不检查(unchecked)异常

可检查异常:在源代码里必须显式的进行捕获处理,这也是编译期检查的一部分。

不检查异常:就是所谓的运行时异常,类似:NullPointerException、ArrayIndexOutOfBoundsException之类的,通常这些都是可以通过编码避免的逻辑错误。可以根据业务需求来判断是否需要进行处理,并不会在编译器进行强制要求。

运行时异常和一般异常有什么区别?

  • 1.定义不同,运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等。一般异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。
  • 2.处理方法不同,运行时异常是不检查异常,程序中可以选择捕获处理,也可以不处理。对于一般异常,JAVA编译器强制要求用户必需对出现的这些异常进行catch并处理,否则程序就不能编译通过。
  • 3.发生原因不同,运行时异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。

四、扩展

(一)NoClassDefFoundError和ClassNotFoundException的区别

NoClassDefFoundError是一个错误(Error),而ClassNotFoundException是一个异常,在Java中对于错误和异常的处理是不同的,我们可以从异常中恢复程序但却不应该尝试从错误中恢复程序。

ClassNotFoundException的产生原因:

Java支持使用Class.forName方法来动态地加载类,任意一个类的类名如果被作为参数传递给这个方法都将导致该类被加载到JVM内存中,如果这个类在类路径中没有被找到,那么此时就会在运行时抛出ClassNotFoundException异常。

解决该问题需要确保所需的类连同它依赖的包存在于类路径中,常见问题在于类名书写错误。

java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver111
//连接数据库
    public static Connection DBHelp_bak(){
        System.out.println("--------------------第一次--------------------");
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            return null;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println(String.format("第一次错误是:%s",e.getMessage()));
        }
        return null;
    }
    //连接数据库  报错的
    public static Connection DBHelp_bak(){
        System.out.println("--------------------第二次--------------------");
        try {
            Class.forName("com.mysql.cj.jdbc.Driver22222");
            return null;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println(String.format("第二次错误是:%s",e.getMessage()));
        }
        return null;
    }

另外还有一个导致ClassNotFoundException的原因就是:在编译过后或者打包过后,人为的去损坏或者篡改jar包或者class文件,也会出现这种异常。

复现步骤:

  • 1、创建一个SpringBoot项目;
  • 2、打成jar包;
  • 3、把jar包中的启动程序删除;
  • 4、重新启动,就会出现ClassNotFoundException异常。
D:\glodonProject\springbootswagger1\target>java -jar springbootswagger1-0.0.2-SNAPSHOT-2.jar
Exception in thread "main" java.lang.ClassNotFoundException: com.OcrbootApplication
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
        at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:348)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:46)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:107)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
D:\glodonProject\springbootswagger1\target>

NoClassDefFoundError产生的原因在于:

如果JVM或者ClassLoader实例尝试加载(可以通过正常的方法调用)类的时候却找不到类的定义。要查找的类在编译的时候是存在的,运行的时候却找不到了。这个时候就会导致NoClassDefFoundError。

视频版

Java的面试知识点技巧集

⬇️

Java的面试知识点技巧集

目录
打赏
0
0
0
0
4
分享
相关文章
|
8月前
|
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
263 1
2025 年 Java 核心技术全面升级与实战应用详解
这份Java校招实操内容结合了最新技术趋势,涵盖核心技术、微服务架构、响应式编程、DevOps及前沿技术等六大模块。从函数式编程到Spring Cloud微服务,再到容器化与Kubernetes部署,帮助你掌握企业级开发技能。同时,提供AI集成、区块链实践和面试技巧,包括高频算法题与系统设计案例。通过学习这些内容,可应对90%以上的Java校招技术面试,并快速上手实际项目开发。资源链接:[点此获取](https://pan.quark.cn/s/14fcf913bae6)。
250 41
|
1月前
|
MinIO Java SDK 7.1.4 升级到 8.5.17 需要注意什么
现在我需要你帮我分析对比这个两个sdk在对外的接口设计上是否有不兼容的变更
102 5
如何避免 Java 中的 TimeoutException 异常
在Java中,`TimeoutException`通常发生在执行操作超过预设时间时。要避免此异常,可以优化代码逻辑,减少不必要的等待;合理设置超时时间,确保其足够完成正常操作;使用异步处理或线程池管理任务,提高程序响应性。
429 13
|
8月前
|
在 Java 中,如何自定义`NumberFormatException`异常
在Java中,自定义`NumberFormatException`异常可以通过继承`IllegalArgumentException`类并重写其构造方法来实现。自定义异常类可以添加额外的错误信息或行为,以便更精确地处理特定的数字格式转换错误。
129 1
深入理解Java锁升级:无锁 → 偏向锁 → 轻量级锁 → 重量级锁(图解+史上最全)
锁状态bits1bit是否是偏向锁2bit锁标志位无锁状态对象的hashCode001偏向锁线程ID101轻量级锁指向栈中锁记录的指针000重量级锁指向互斥量的指针010尼恩提示,讲完 如减少锁粒度、锁粗化、关闭偏向锁(-XX:-UseBiasedLocking)等优化手段 , 可以得到 120分了。如减少锁粒度、锁粗化、关闭偏向锁(-XX:-UseBiasedLocking)等‌。JVM锁的膨胀、锁的内存结构变化相关的面试题,是非常常见的面试题。也是核心面试题。
深入理解Java锁升级:无锁 → 偏向锁 → 轻量级锁 → 重量级锁(图解+史上最全)
【YashanDB知识库】yasdb jdbc驱动集成BeetISQL中间件,业务(java)报autoAssignKey failure异常
在BeetISQL 2.13.8版本中,客户使用batch insert向yashandb表插入数据并尝试获取自动生成的sequence id时,出现类型转换异常。原因是beetlsql在prepareStatement时未指定返回列,导致yashan JDBC驱动返回rowid(字符串),与Java Bean中的数字类型tid不匹配。此问题影响业务流程,使无法正确获取sequence id。解决方法包括:1) 在batchInsert时不返回自动生成的sequence id;2) 升级至BeetISQL 3,其已修正该问题。
【YashanDB知识库】yasdb jdbc驱动集成BeetISQL中间件,业务(java)报autoAssignKey failure异常
【YashanDB知识库】yasdb jdbc驱动集成druid连接池,业务(java)日志中有token IDENTIFIER start异常
客户Java日志中出现异常,影响Druid的merge SQL功能(将SQL字面量替换为绑定变量以统计性能),但不影响正常业务流程。原因是Druid在merge SQL时传入null作为dbType,导致无法解析递归查询中的`start`关键字。
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
296 14
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问