大数据JAVA基础第十四天

1.Java异常

在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的,比如:客户输入数据的格式,输入值的范围,读取文件是否存在,网络是否始终保持通畅等等。

对于程序设计人员需要尽可能的预知所有可能发生的情况,尽可能的保证程序能在所有最糟糕的情况下都能运行。

但实际上,意外情况是不胜枚举的,程序可能发生的异常情况远远多于程序员所能考虑到的意外情况。

Java的异常处理机制可以让程序具有良好的容错性,让程序更加健壮,当程序出现异常时,系统会自动生成一个Exception对象来通知程序,从而实现将“业务功能实现代码”和“错误处理代码”分离,使程序具有更好的可读性。

2.异常Exception

异常指的是在运行期出现的错误,在编译阶段出现的语法错误等,不能称之为异常

Java程序在运行期所发生的异常事件可分为两类:Error Exception,不包含语法错误等这些错误,下图是Java中异常类的继承关系图:

 

  • Error

Java虚拟机无法解决的严重问题。如:JVM系统内部错误,系统崩溃,动态链接失败等等,这种错误无法恢复或不可能捕获,将导致应用程序中断,通常程序无法处理这些错误,因此程序中不要试图使用catch块来捕获Error对象。一般不进行处理。

  • Exception

其它因程序设计错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:算数异常,空指针访问,数组下标越界,所要读取的文件不存在等等

l  主要分成两类:

l  一类是编译异常,必须处理之后才能正常编译(类找不到,IO异常...在API文档中明确写明throws...的方法,必须要进行处理)

l  一类是运行时异常RuntimeException,这种异常可以处理,也可以不处理(算数异常,空指针等)

3.运行时异常

是指编译程序不要求强制处置的异常。一般是指程序设计时的逻辑错误,是程序员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常。

对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。

4.编译异常

是指编译程序要求必须处置的异常。

Java程序必须捕获或声明所有编译时异常。

对于这类异常,如果程序不处理,可能会带来意想不到的结果,编译都不能通过

5.运行时异常的解决方法

对于这些运行时异常(不是编译异常),一般有两种解决方法:

  • 一是遇到错误就终止程序的运行,即不对异常进行处理
  • 二是由程序员在编写程序时,就考虑到错误的检测、错误消息的提示,在抛给Java运行时环境的时候,就将这个异常对象捕获,再进行处理(打印提示信息等)

try尝试:将可能发生异常的语句放入其中

catch捕获:当try块中的异常发生时,将产生一个异常对象,拿这个对象去匹配catch块中的异常类,如果和catch中的类型匹配了,就执行这个catch块中的语句,这也就意味着,catch块可以有多个。

从以上程序可以看出,一个try后可以加多个catch块,针对try语句块中发生的异常分别捕获,当然,只能有一个catch块被执行,从执行的逻辑上看,和switch分支语句很相似。

如果把Exception类对应的异常catch块放在前面的话,一旦发生错误,将直接进入该catch块,因为所有的异常都是Exception或其子类的实例,而排在它后面的catch块将永远也不会得到执行的机会。

实际上,进行异常捕获时,不仅应该把Exception类对应的catch块放在最后,而且所有父类异常块都应该排在子类异常catch块的后面,简记为:先处理小异常(子),后处理大异常(父)。否则编译出错

6.访问异常信息

如果程序需要在catch块中访问异常对象的相关信息,可以通过访问catch块后的异常形参来获得,当Java运行时决定调用某个catch块来处理该异常对象时,会将异常对象赋值给catch块后的异常参数(即:异常类型的形参),程序即可通过该参数来获得异常的相关信息。

所有的异常对象都包含了以下几个常用的方法:

  • getMessage():返回该异常的详细描述信息
  • printStackTrace():将异常的跟踪栈信息打印出来
  • printStackTrace(PrintStream s):将异常的跟踪栈信息输出到指定的输出流
  • getStackTrace():返回该异常的跟踪栈信息

7.类型转换异常:ClassCastException

import java.util.Date;

public class ErrorDemo {

    public static void main(String[] args) {

       Object obj = new Date();

       String str = (String)obj;

    }

}

8.空指针异常:NullPointerExcetion

    @Test

    public void test5(){

       String str = new String("AA");

       str = null;

       System.out.println(str.length());

    }

9.编译时异常(必须捕获)

在API中查看方法声明后带throws关键字的

import java.io.FileInputStream;

import java.io.FileNotFoundException;

public class ErrorDemo {

    public static void main(String[] args) {

       FileInputStream in = null;

       // in = new FileInputStream("a.txt");//error,没有捕获

       try{

           in = new FileInputStream("a.txt");//有可能会抛出异常,必须捕获

       }catch(FileNotFoundException fe){

           fe.printStackTrace();

       }

    }

}

10.使用finally回收资源

有的时候,在try语句块中打开了一些物理资源,如数据库连接,网络连接,磁盘文件等,这些物理资源都必须显式回收。

Java中的垃圾回收机制不会回收任何物理资源,垃圾回收机制只能回收内存中对象所占用的内存资源。

那么在哪里回收物理资源呢?能在try语句块中么?如果try块中执行某条语句出现异常的话,则该语句之后的语句都没有机会执行,这将导致其后的资源回收语句得不到执行。如果在catch块中执行资源回收的话,catch语句块也完全有可能得不到执行,这也会导致资源不能得到回收。

为了保证一定能够回收在try块中打开的物理资源,异常处理处理机制提供了finally块,不管try中的哪一条语句出现异常,也不管哪一个catch块被执行,甚至在try或者catch中执行了return语句,finally块总会被执行。完整的异常处理结构语法如下:

try{

    业务处理语句

}catch(异常1 e1){

    异常处理语句

}catch(异常2 e2){

    异常处理语句

}

...

finally{

    资源回收语句

}

11.注意:

在异常处理的结构中,只有try块是必须的,也就是说,如果没有try块,则不能有后面的catch和finally块,catch和finally两者至少出现一个,当然也可以同时出现;捕获子类异常的catch块必须位于捕获父类异常catch块的前面;finally块应该位于所有的catch块后面

12.注意事项:

通常情况下,不要在finally块中使用return或者thorw等导致方法终止的语句,(throw后面讲),一旦在finally块中使用了return或者throw语句,将会导致try块,catch块中的return,throw语句失效。

当程序在try/catch中遇到了return或者是throw语句,程序停止执行,但是并不会立即结束该方法,而是去寻找是否包含了finally块,如果没有finally块,则立即执行return或者throw语句,方法终止;如果有finally块,程序立即开始执行finally块,只有当finally块中语句执行完了,系统才会返回到try块中执行return或者是throw语句;如果finally块中也包含了return或者是throw等导致方法结束的语句,则在finally块中已经终止了方法,程序就不会再跳回去执行try块,catch块中的任何代码。换句话说,在finally中的return语句提前终止了方法。

13.提示:

尽量避免在finally块中使用return,throw等语句,会导致一些非常特别,难以察觉的错误,不利于程序开发。

原文地址:https://www.cnblogs.com/xiejiajun/p/6636186.html