Java中的异常处理机制(异常一般用于怕输入的时候输入违法的内容导致程序瘫痪,所以提前写好异常,遇到输入错误会有提醒)

1、java异常处理机制存在的目的:
保证了程序的容错性,允许程序出现某些错误(比如输入错误),程序不会因为这些错误而突然退出,程序会向用户提示输入不合法,让用户再次输入。
2、关键字的含义:
try:try块里面放置可能引发异常的代码。
catch:后面有一个异常类型和代码块,用于表明catch块用于处理这种类型的代码块。
finally:多个catch块后面还可以跟一个finally块,finall块用于回收再try块里打开的屋里资源,异常机制会保证finally块永远被执行。
throws:在签名中使用,用于声明该方法可能抛出的异常。
throw:用于抛出一个实际的异常,throw可以单独作为语句使用,抛出一个具体的异常对象。
3、执行过程:

try{
     //业务实现代码
}
catch (Exception e){
       //处理机制
       //Exception是所有异常类的父类
}

如果执行Try里的业务逻辑代码时 出现异常,系统会自动生成一个异常对象,该对象被提交给java运行时环境,这个过程被称为抛出(throw)异常
当java运行时环境收到异常对象时,会寻找能处理这个异常对象的catch块,如果找到合适的catch块,则把该异常对象交给该catch块处理,这个过程称为捕获(catch)异常,如果java运行环境找不到捕获异常的catch块,则运行环境终止,java程序也将退出。
4、异常类的继承体系
(先处理小异常,再处理大异常)也就是说所有父类异常的catch块都应该排在子类异常catch块的后面。因为当java运行环境接收到异常对象后,会依次判断该异常对象是否是catch块后异常类或者其子类的实例,如果是,则java运行环境将调用该catch快来处理该异常,否则再次拿该异常和下一个catch块里的异常进行比较。所以如果父类在前面,那么子类处理机制将永远不会被执行。
一般情况下,如果try块被执行一次,则try块后面只有一个catch块会被执行,绝不可能有多个catch块被执行。除非循环中使用了continue开始下一次循环,下一次循环又重新运行了try块,这才导致多个catch块被执行。
5、几种常见的运行时异常
(1)IndexOutOfBoundsException(如果运行该程序时输入的参数不够,将会发生数组越界的异常)
(2)NumberFormatException(如果运行该程序时输入的参数不是数字,而是字母。将会发生数字格式异常)
(3)ArithmeticException (算数异常)
(4)NullPointerException(空指针异常)
(5)Exception(未知异常,所有异常的父类)
注意:try块里声明的变量是局部变量。它只在try块内有效,在catch中不能访问该变量。
6、多异常捕获
在java7之前,每个catch块只能捕获一种类型的异常,但是从java7开始,一个catch块可以捕获多种类型的异常。
注意:(1)捕获多种类型的异常时候,多异常之间用(|)隔开
(2)捕获多种类型的异常时候。异常变量有隐式的final修饰,因此程序不能对异常变量(也就是catch后面的异常类型对象)重新赋值。但是单个异常的时候没有隐式的final。可以对异常变量进行重新赋值。
7、访问异常信息
如果程序需要在catch块中访问异常对象的相关信息,则可以通过访问catch块的后异常形参(也就是catch括号里的异常类型对象)来获得。
所有的异常对象都包含如下几个常用方法
(1)getMessage():返回该异常的详细描述字符串
(2)printStackTrace():将该异常的跟踪栈信息输出到标准错误输出
(3)printStackTrace(PrintStream s):将该异常的跟踪栈信息输出指定输出流
(4)getStackTrace():返回该异常的跟踪栈信息
想访问就可以如下形式:
catch(Exception ie)
ie.getMessage()
8、使用finally回收资源
定义:有些时候,程序在try块里打开了一些物理资源(例如数据库的连接,网络连接,和磁盘文件等)这些物理资源都必须在finally中显示收回
注意:Java的垃圾回收机制不会回收任何的物理资源,垃圾回收机制只能回收堆内存中对象所占用的内存。
例如下面的示例代码:

package com.imooc.test;
//下面这两个包必须导入
import java.io.IOException;
import java.io.*;
public class FinallyTest {
	public static void main(String[] args){
        FileInputStream fis=null;
        try{
             fis=new FileInputStream("a.txt");
        }
        catch(IOException ioe){
            System.out.println(ioe.getMessage());
            return;
            //使用exit退出虚拟机
            //System.exit(1);
        }
        finally{
            //关闭磁盘文件,回收资源
            if(fis!=null)
            {
               try{
                     fis.close();
                  }
                  catch(IOException ioe)
                  {
                       ioe.printStackTrace();
                  }
            }
            System.out.println("执行finally块里的资源回收!");
        }
   }
}

Java中的异常处理机制(异常一般用于怕输入的时候输入违法的内容导致程序瘫痪,所以提前写好异常,遇到输入错误会有提醒)_第1张图片
这就是运行结果:
注意:一般情况下,一旦方法里执行到return语句的地方,程序就会立马结束。但是现在不会了,以下是执行过程:
执行过程:当java中执行try,catch,块时遇到return,throw语句时候,这两个语句都会导致该方法立即结束,但是系统执行这两个语句并不会结束该方法,而是去寻找该异常处理流程中是否包含finally块,如果没有finally块,程序立即执行return或throw语句,方法终止,如果有finally块,系统开始立即执行finally块。只有当finally块执行完成后,系统才会跳回来执行try块,catch块里的return或者throw语句;但是如果finally里也有return或者throw语句,那么程序在finally就会终止,则不会跳回去执行try块,catch块里的任何代码。(所以finally里一般不要用return或者throw语句)
所以在这程序里。执行System.out.println(ioe.getMessage());输出a.txt(系统找不到指定的文件)。然后执行finally块。再回来执行catch里的return,程序结束。
但是还要注意:如果在try里不注释掉System.exit(1);的话。那么finally则不会被执行。因为如果在异常处理代码中使用System.exit(1);语句来退出虚拟机,则finally块将失去执行的机会。
所以总结:除非在try,catch块中调用了退出虚拟机的方法,否则不管在try,catch块中执行怎样的代码,出现怎样的情况,异常处理的finally块总会被执行。
9.也可以隐式的执行finally块(即自动关闭资源,java7中新功能)
它允许在try关键字后面紧跟一对圆括号,括号里可以声明,初始化一个或多个资源,此处的资源指的是那些必须在程序结束时显示关闭的资源(比如数据库连接,网路连接等),try语句在该语句结束时会自动关闭这些资源。
注意:为了保证try语句可以正常关闭资源,这些资源实现类必须实现AutoCloseable或Closeable接口,实现这两个接口就必须实现close()方法。例如:

try (
//声明,初始化两个可关闭的资源
//try语句会自动关闭这两个资源
BufferedReader br=new BufferedReader(new FileReader("AutoCloseable.java"));
PrintStream ps=new PrintStream(new FileOutputStream("a.txt"))
)

9、用throws显示声明抛出Checked异常:这是一个不太好的操作,所以不写了,具体书上368-370页
但是注意:如果某段代码中调用了一个throws声明的方法,该方法声明抛出了Checked异常,则表明还方法希望它的调用者来处理该异常。也就是说,调用该方法时要么放在try块中显式捕获该异常,要么放在另一个带throws声明抛出的方法中。
10、使用throw抛出异常(一般都是由于与业务需求不符而产生的异常,必须由程序员来决定抛出,系统无法抛出该异常)
定义:如果需要在程序中自行抛出异常,则应使用throw语句,throw语句可以单独使用,throw语句抛出的不是异常类,而是一个异常实例,而且每次只能抛出一个异常实例。
throw ExceptionInstance(异常实例)
(1)当程序接收到开发者自行抛出的异常的时候,同样会终止当前的执行流,跳到该异常对应的catch块,由该catch块来处理该异常。也就是说,不管是系统自动抛出的异常,还是程序员手动抛出的异常。Java运行时环境对异常的处理没有任何差别。
(2)如果throw语句抛出的异常是Checked异常,则该throw语句要么处于try块里,显式捕获该异常,要么放在一个带throws声明抛出的方法中,即把该异常交给该方法的调用者处理;如果throw语句抛出的是Runtime异常,则该语句无需放在try块里,也无须放在带throws声明抛出的方法中;程序即可以显式使用try…catch来捕获并处理该异常,也可以完全不理会该异常,把该异常交给该方法调用者处理。
11、自定义异常类

你可能感兴趣的:(技术)