classnotfoundexception是什么异常_碰见异常 你是选就地正法 还是甩锅大法

c698a2644e294197ff978d177524b09e.png

java零基础入门-高级特性篇(九) 异常 中

上一节讲到了检查异常,这种必须处理的异常到底该怎么处理呢?通常的处理方式就是捕获异常或者抛出异常,捕获异常就是在异常出现的时候当场解决,而抛出异常则是把锅甩出去,把异常往上层抛出,让上层逻辑来解决它。处理异常有专门的关键字,java中的异常家族里有以下几种关键字,try、catch、finally、throw、throws,下面来分别介绍它们。

捕获异常

捕获异常就是当场就地正法,使用try和catch关键字来处理异常。try用来监视代码逻辑的运行,如果没有异常,那么程序会一直运行到结束,而一旦发生异常,并且在try的监控范围之内,那么程序就会跳转到catch部分,运行catch里面的代码。如果没有捕获异常,程序会直接结束,所以捕获异常可以给我们一次挽救程序异常停止的机会,就算不能挽救,也至少可以知道为什么程序会出现异常。

8382579060d526d842ec75c919bdf350.png
try-catch

上面这个try-catch结构就是基本的捕获异常结构,try后面的程序就是正常的逻辑代码,catch后面是如果发生了异常需要执行的代码。需要注意的是,在出现异常以后,不会继续执行程序,而是直接跳到catch部分执行代码,所以这里输出完第一个打印语句以后就马上输出了异常信息。

e是Exception的对象,调用Exception父类Throwable的方法printStackTrace(),输出异常信息,输出异常信息有多种方式,printStackTrace()是一种,这种方式输出的是最详细的错误信息,包括出现异常代码的行号,异常信息和异常原因,这种方式适合调试程序,找到错误。还有一种getMessage(),这种输出只会输出异常的信息,比上面一种方法输出的信息要少,这种方式适合记录日志,将错误的信息作为日志记录下来,以便需要的时候排查问题。

多个异常的捕获结构

上面的例子是使用Exception捕获的异常,其实理论上来说,应该使用最准确的异常来捕获,由于Exception是所有异常的父类,所以使用Exception没有问题,但是最适当的方式是使用FileNotFoundException来捕获这里的异常。为什么要用子类来捕获异常?因为使用子类捕获异常可以将异常处理的更加精细,比如下面这个例子。(里面流和反射的知识可能没有学到,但是此处只需关注异常即可)。

da1f452e3807f7bb2b5432505f26dca7.png
使用子类捕获

当一段逻辑中有可能出现多个异常需要捕获的时候,如果直接使用Exception,那么只能执行一个异常逻辑,而不能将不同的异常区分开。这样就导致无法根据不同的异常进行不同的异常处理。当一段逻辑中出现多个需要捕获的异常的时候,可以在try后面接多个catch,分别对不同的异常类型进行捕获。

9202970f659062e786b2f8b2884477ed.png
同时使用

Exception和Exception的子类在捕获异常的时候是不冲突的,但是子类的捕获必须在父类之前,如果第一个catch的是Exception,那么他会直接捕获所有异常,不能单独处理其他异常了。异常捕获的顺序是按照异常出现的顺序来的,如果首先出现的是文件找不到异常,那么会被FileNotFoundException捕获,如果首先出现的是ClassNotFoundException,那么会被Exception捕获。

有finally的结构

讲完try和catch关键字以后,再来看另一个关键字finally。在处理异常的时候,try关键字是必须出现的,有了try关键字,程序才会在try所包含的代码块中捕获异常,而catch和finally是可以任意出现一个的,也可以两个同时出现。finally的特性是,不论在catch中是否出现异常,finally中的代码都会被执行。因为有一些代码如果写在try中,如果出现异常,那么这些代码是可能不会被执行的,如果写在catch中,如果不发生异常也不会执行,所以需要一个地方来写无论是否出现异常都会被执行的代码。

9a22c7c4e6803ce5690e1f35c3d353f8.png
finally

finally在处理资源的时候非常有用,比如IO,网络,数据连接等等,因为在使用这些资源的时候需要在代码中手动的回收,但是如果发生异常就不会执行到回收资源的代码,所以在finally中回收资源是一种很好的选择。

使用finally需要注意的几个地方:

1.如果有一个或多个catch关键字的话,finally要出现在最后一个catch之后。顺序如果有错误会发生编译错误。

2.不建议在finally里面使用return关键字。

14088c7b6576feb7942154a13e0b4d50.png
finally中的return

在finally里面是可以使用return关键字的,但是会导致结果与预期不符合。比如上面这个例子,上例中其实是不检查异常,可以捕获也可以不捕获,这里为了说明finally就捕获异常了。这里预期返回的是两个参数的商,程序运行到try中的return是不会马上结束方法的,因为后面有finally语句,而finally语句中也有return,最后的结果就是finally中的return导致try中的return无效。无论程序是否发生异常,方法预期返回的结果都被改变了,返回的不是程序希望得到的两个参数的商,而是一个与参数无关的字符串,所以通常不建议在finally中使用return关键字。

final ,finally 和finalize

这个地方要指出的是,这几个关键字八竿子打不着关系,但是经常会有外行题目问这几个关键字有什么区别。这里简单说一下。

final 定义的变量,初始化变量后不可修改。final定义的方法不可以被覆写。final定义的类不可以继承。

finally用于异常结构,不论是否发生异常,都会运行finally中的代码。

finalize用于定义垃圾回收器应该执行的操作。

抛出异常

捕获异常讲完了,轮到抛出异常了。前面说了检查异常,有没有想过,为什么检查异常就必须处理呢?因为在定义类,方法的时候,源码已经将异常抛出了,所以你在使用类的时候就必须处理它,要么捕获,要么抛出。前面例子中

FileOutputStream out = new FileOutputStream(file);

会有一个FileNotFoundException类型的异常必须处理,来看看FileOutputStream这个类的构造器。

e2bb49e689c87b19e47a315a5c355cf9.png
抛出异常

什么是抛出异常?

抛出异常就是遇到检查异常,并没有捕获异常直接处理,而是将异常交给调用方处理。

为什么要抛出异常而不是直接捕获?

因为设计上的需要。当我们在写一个业务的时候,碰见异常最好的方法就是捕获并处理它。但是如果写的是一个公共的工具方法或者是父类,抽象类等需要将业务进行抽象的时候,并不能预见到具体的业务是什么,所以不能直接给出解决方案,这时候就需要将异常交给调用方,在使用者具体使用的时候,再来捕获该异常,根据具体情况确定具体的处理方式。

异常具体是怎么抛出的?

c722205d452b8b2ca870d834ff220f13.png
异常的抛出

首先在一个需要抛出异常的地方将异常往上一级(方法的调用者)抛出,然后上一级还可以继续往上一级抛出,如果到最后都没有被捕获,该异常会被抛给jvm,jvm也没法处理异常只能把异常信息打印出来。

这个过程就像出了问题,开始甩锅一样。方法A出了问题,自己可能没有办法处理,就把锅甩给了方法B,方法B一看这个我也没法解决啊,转手又甩了出去,最后这个锅被甩给了老大哥JVM,JVM老大哥看到异常也只能干瞪眼,没有办法最后只能把异常信息打印出来,谁写的代码谁来认领一下,错误给你看了,自己想办法去解决。

e2b227653632112d67b97f0a458046ff.png
抛出异常

java使用关键字 throws 抛出异常,throws后面跟上异常的类型,跟catch的捕获类型差不多,定义什么类型的异常就会抛出什么类型的异常,如果直接抛出Exception,那么就是抛出所有的异常类型。跟catch可以捕获多种异常类型一样,throws也可以抛出多种异常类型,这样就可以让上一级的代码根据不同的异常类型分别进行处理。如果只抛出Exception类型的异常,上一级就无法对异常进行精确的控制了。

942b252a45707d3108b086c1c4e220c7.png
抛出多个异常

使用throws同时抛出多个异常的时候,使用逗号将多个异常分开。throws这种抛出异常的方式可以看做是一种被动式抛异常,因为throws抛出的异常可能发生也可能不发生,java中除了throws抛出异常,还有一种主动式抛异常,下面来看看什么是主动式抛异常。

throws 和 throw

主动抛出异常的关键字是throw。和throws只差了一个小写字母s,这里需要重点区分开两种异常抛出方式的区别。

throws:1)抛出的是类,在方法后面写的是异常的类名 2)可以同时抛出多种类型异常 3)throws抛出的异常不一定会发生 4)在方法名处抛出

throw:1)抛出的是异常类的实例 2)只能抛出一种异常 3)抛出的异常一定会发生 4)在方法内部抛出

throw用在抛出不检查异常的情况比较多。使用throw可以将代码的逻辑补充的更加完整,因为某些异常在特定的情况是需要根据业务逻辑来判断是否抛出,在特定的情况下是可以确定异常的,而不是像throws不确定是否会出现异常。这种情况下就可以使用throw在方法体中抛出异常。

6bda05bcc1e4e30b89fb46f11942c995.png
throw

上例中,假设用户需要输入两个数字,然后计算两个数字的商。用户输入是不确定的,但是一旦用户将intTest2输入为0,代码逻辑可以确定这里肯定会有一个异常,那么可以直接使用throw来抛出这个异常。一旦在调用方法时捕获到该异常,也可以确定异常的信息,比如上例中可以将捕获到的信息直接反馈给用户,第二个数不能为0。

需要注意的是throw只是抛出异常的方式比较灵活,可以在代码逻辑中抛出异常,而抛出异常以后,上级的处理逻辑和throws是一样的,要么继续往上级抛异常,要么捕获异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ClassNotFoundException是Java中的一种异常,表示在运行时找不到类。当Java虚拟机(JVM)尝试加载类时,如果找不到该类,则会抛出ClassNotFoundException异常。这通常发生在以下情况下: 1.类名拼写错误或类文件不存在。 2.类文件存在,但未在类路径中找到。 3.类文件存在,但缺少依赖项。 4.类文件存在,但不兼容当前JVM版本。 当出现ClassNotFoundException异常时,应检查类名拼写是否正确,类文件是否存在,类路径是否正确,以及是否缺少依赖项。 ### 回答2: ClassNotFoundException是Java中的一个运行时异常,表示试图加载某个类的时候,该类无法找到。通常情况下,当编写Java应用程序时,编译器会自动检查类的引用是否正确。但在运行时,如果程序试图使用某个类,而该类未被正确加载,就会抛出ClassNotFoundException异常。 通常情况下,ClassNotFoundException异常发生是由于以下原因导致的: 1. 类名拼写错误:输入类名错误时,编译器无法从类路径中找到该类。 2. 缺少依赖:如果程序中使用的类依赖于其他库,而这些库未在classpath中,就会导致该类无法找到。 3. 类被删除或移动:如果程序运行时,对应的类被删除或移动到其他位置,就会导致ClassNotFoundException异常。 4. Java虚拟机版本不匹配:如果程序是在一个高版本的Java虚拟机上编译,而在低版本的Java虚拟机上运行,就会发生ClassNotFoundException异常。 当出现ClassNotFoundException异常时,通常会在控制台打印异常信息,包括异常类型名称、“类名”和堆栈跟踪信息。要解决此类异常,需要仔细检查代码中是否存在类引用问题,以及类路径是否正确等。通常情况下,遵循最佳实践,使用适当的类路径和正确的类名,可以避免此类异常的发生。 ### 回答3: ClassNotFoundException是一种Java编程语言中的运行时异常。当尝试在程序中加载一个类时,如果Java虚拟机无法找到这个类或该类的实现文件,则会抛出ClassNotFoundException异常。它通常出现在以下三种情况: 1. 试图在代码中使用一个不存在的类,或者试图将类的实例化对象格外转型为一个不属于该类继承链上的类。 2. 在一个特定的类中,应用程序动态的加载一个类,但是加载的类不在类路径上。 3. 使用 MySQL 的 JDBC 驱动进行数据库操作时,可能会遇到 ClassNotFoundException 异常,原因是JDBC驱动没有在类路径中正确加载。 通常可以通过以下几种方式来解决 ClassNotFoundException 异常: 1. 检查代码是否存在语法错误,确保正确引用了所需的类。 2. 检查类路径是否正确,并且尝试将类路径添加到CLASSPATH环境变量中。 3. 确保所有所需的库已包含在运行时类路径中。 总之,ClassNotFoundException异常通常是由于编程时类的路径没有正确加载所致。解决方法包括添加正确的类路径,确保正确引用了所需的类等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值