Java基础复习笔记系列 三

时间:2022-02-08 22:16:31

前几节都是基础中的基础,从第三讲的笔记开始,每次笔记针对Java的一个知识块儿。

 Java异常处理

 

1、什么是异常?

  异常是指运行期出的错误。比如说:除以一个0;数组越界;读取的文件不存在。

  异常处理,要把异常控制在程序员合理范围之内。如数组越界indexOutOfArray,在用户看来是不可以被理解的,所以,程序员要捕获这种异常,反馈到前端告诉用户是“超出了范围”。

  Java中针对异常事件,自动生成一个异常对象。这个异常对象封装了异常事件的信息并将其提交给Java运行时系统。Java运行时系统会把异常对象中封装的异常事件信息打印到控制台上。我们所做的就是,在他交给Java运行时系统之前,捕获异常。那么问题来了,我们该怎么捕获异常呢?使用catch语句。如catch(ArithmeticException e)这个ArithmeticException异常时由Java运行时帮你生成的。catch什么时候被用,异常的时候用呗,要搭配try一起来用。如在微软产品中,系统现在出错,你是否愿意将这个错误报告给我们。

  那么throws呢?throws是用在方法上的。throws说明用我这个方法可能出现的异常。如NullPointerException.

2、异常中的体系结构?

  Throwable是一个根类。它下面有一个Exception类,一个Error类。Error是系统的内部错误,程序员管不了。Exception是程序员可以解决的异常。那么Exception类下面又分为RuntimeException类和非RuntimeException类。

  RuntimeException可以不用catch;但是非RuntimeException必须得catch。在JDK的API中的方法后面throws的异常,都是非RuntimeException异常。如IOException。这些异常必须捕获。否则,程序无法运行。

  printStackTrace,将可能引起异常的所有原因都打印出来了。从字面上看,就是所有Stack的轨迹。

  总结:throwable-->Error

          -->Exception-->RuntimeException

                -->非RuntimeException(必须捕获)

  比如说像:FileInputStream in = new FileInputStream("123.txt");这种语句在Eclipse中,如果不用try...catch语句来包裹的话,它的小红叉会提醒你:unhandled exception of FileNotFoundException.然后紧跟着在它的下面会提醒有:Add throws Declaration或者Surround with try/catch.可见,我们得出了结论。对于JDK API文档中的方法中throws的异常,必须要捕获。否则的话,程序有bug。

3、try包含的语句中可能有多个异常的时候,可以在后面搭配使用多个catch。

  事情的逻辑是这样的:try...catch/catch/catch...finally.finally中的代码都会执行。也就是说,不管不产生异常,finally中的代码都会被执行。

  为什么要引入这个机制呢?当catch住一个Exception的时候,程序就不会执行了。让finally中的语句不管什么状态都执行,保证了程序能正常的运行下去。finally为异常部分提供了一个统一的出口。finally一般用于资源的清除工作,如关闭打开的文件,删除临时文件。

4、对于处理不了的异常,怎么处理?

  try...catch这种结构中,catch是用来捕获处理异常的结构。那么,如果我们处理不了的异常,怎么办呢?那就用到了另外一个关键字throws.

  void function( )throws FileNotFoundException, IOException{ }这样,你只负责把这段代码的异常抛出。你只要往外抛就可以了,因为处理不了。那么,当别的函数要调用的时候,那么就要写try...catch了或者在接着用throws异常。

  但是,最终异常一定要被处理,不能再程序中自己吞掉。这样程序还怎么进行维护?e.printStackTrace()(把它的所有的堆栈的信息都打印出来)或者用log4J将它记录在日志文档中。

  最屌丝的做法就是在public static void main方法上用throws来抛异常,这样将异常交给了Java运行时系统。异常是程序员应该做的事,教给Java运行时系统做事很不好的编程习惯。

5、知识补充待续:

  异常处理的函数,要被另外一个函数所调用。它们可以一级一级的使用throws来抛异常,不处理异常,但是最终的最终,都必须要用try...catch来捕获处理异常,而千万不能把它们交给Java运行时系统来处理。

  我们在调试代码的时候,比如数组越界一个错误,在控制台上,会看到抛出了一系列的错误。它们都是基于e.printStackTrace来打印出的异常。而且因为它们各级之间都是用throws来抛异常,不处理异常,所以,才会,一个bug,会把栈空间的所有exception打印出来。因为你要知道,在Java的API中,好多函数也仅仅是throws异常,而不处理。这个时候,要关注at...(Test.java 18),关注at后面的内容,提示了哪个文件中的第几行出错了。

6、catch的时候,要注意一下catch的顺序问题。

  首先捕小的,子类的异常。再捕获大的,如Exception异常。假如先捕获了Exception异常,那么后面的异常就不可能再被捕获到了。

  异常抛出之后,try中剩余的部分是不会被执行的。

  重写方法,需要跟原方法抛出一模一样的异常,不能大,不能小。但是你可以不用写throws。切记!

7、自定义异常?

  自定义异常,自己生成自己的异常类。你只要继承Exception或者继承RuntimeException就可以了。如:登陆网页的时候,我们自定义异常,user Not found异常;或者password is uncorrect异常。

  异常写的精细点儿,就是用户名错误,或密码错误,或校验码错误。写的粗糙,就是错误。很显然,第一种异常是一种比较好的效果。