博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java10-异常处理
阅读量:6878 次
发布时间:2019-06-26

本文共 5789 字,大约阅读时间需要 19 分钟。

1.概述

  异常是程序在运行过程中产生的非正常情况,换句话说,异常就是运行时错误。在不支持异常处理的编程语言中必须手动检查错误,java避免了这个麻烦,并且在处理过程中采用面向对象的方式管理错误。

  java中的异常是用来描述代码在运行过程中产生的错误及错误位置的对象。在产生异常时就会创建用来表示异常的对象,并在引起错误的方法中抛出异常对象。方法可以选择自己处理异常,也可以继续传递异常。

  无论采用什么形式,在某一点都会捕获并处理异常。异常可以有java运行时系统生成,也可以通过代码手动生成。

  java抛出的异常与那些违反java语言规则或java执行环境的约束的基础性错误有关。

  java中的异常通过5个关键字进行管理:try、catch、throw、throws、以及finally。后续文章会逐一进行介绍 

2.异常的类型

  java中的异常都是内置类Throwable 的子类(注意Throwable是一个抽象类,并不是接口)。因此,Throwable位于异常类层次中的顶部。

  紧随Throwable之下的是两个子类,他们将异常分为两个不同的分支。一个分支是Exctption类。这个类既可以用于用户程序异常应当捕获的情况,也可以用于创建自定义异常类型的子类。Exception有一个特别重要的子类是RuntimeException

  这种类型的异常是自动定义的,包括除零异常和空指针或者数组越界等。另一个分支是Error类,该类定义了在常规环境下不希望由程序捕获的异常。Error类型的异常由java运行时系统使用,以指示运行时环境本身出现了某些错误。堆栈溢出

  是这类错误的一个例子。他们通常是为了响应灾难性失败而创建的,程序一般不能处理这类错误。

3.未捕获的异常

  未捕获的异常就是我们没有进行处理的异常,比如程序运行过程中出现了除零异常。这时程序会构造一个新的对象,然后抛出这个异常。这会导致执行该方法的线程终止。因为一旦抛出异常,就必须有一个异常处理程序捕获异常

  并进行处理,如果没有任何程序捕获异常并进行处理则会由java运行时系统提供的默认异常处理程序捕获并进行处理。默认异常处理程序会显示一个描述异常的字符串,输出异常发生的堆栈踪迹并终止程序。(一般的输出信息都可以定位到异常)

4.try和catch

  尽管运行时系统默认的异常处理程序可以帮助我们定位到异常发生的位置,但是有一些时候我们还是希望自己来处理异常,自己处理异常有两个优点:

    1.允许修复错误      2.阻止程序自动终止

  为了防止并处理运行时产生的错误,可以简单的在try代码块中监视被执行的代码,紧随在try代码块之后,一般都会有一个catch代码块并且指定希望捕获的异常类型。

  几点注意:try代码块中的代码是可能发生错误的代码,一旦代码发生错误,则程序会跳转到相应的catch语句。try中发生错误的语句及其后面的语句都将不会被执行。换句话说catch不是“调用“,一旦执行了catch,就不可能再回到try中。

  如下这段例子中,“这是异常发生之后” 这句话永远不可能被执行,因为try中发生除零异常之后,就跳转到catch而不会再继续执行try中之后的代码。

public class TestException {    public static void main(String[] args) {        try {            System.out.println(1/0);            System.out.println("这是异常之后");        }catch (Exception e) {            System.out.println("发生了异常" +e);        }    }}//发生了异常

  显示异常

      Throwable类重写了Object类的toString方法,从而可以返回一个包含异常描述信息的字符串。

5.多条catch语句

  有些情况下,try语句块中的代码可能会引发多种异常,将他们放在一个try中,后面可以使用多个catch语句块进行异常捕获。当try中语句产生异常时,会按顺序检查catch语句中的异常,并执行类型可以和异常进行匹配的第一个catch块,

  当执行了一个catch块之后,就会忽略其他的catch块。并继续执行try/catch后面的代码。

  注意:当有多条catch语句块时,异常子类一定要在异常父类之前,因为超类的异常可以捕获子类的异常。因此,如果超类异常在前的话,子类异常永远都不会被捕获到,java中认为不可达的代码是一个错误。

  

public class TestException {    public static void main(String[] args) {        try {            int[] arr = new int[5];            arr[3] = 5/0;            arr[10] = 6;        }catch (ArithmeticException e) {            System.out.println("除0异常" +e);        }catch (ArrayIndexOutOfBoundsException e){            System.out.println("数组越界 "+e);        }catch (Exception e) {            System.out.println("抛出一个异常 "+e);        }        System.out.println("捕获异常之后继续执行");    }}//除0异常java.lang.ArithmeticException: / by zero//捕获异常之后继续执行

 

6.throw 主动抛出一个异常

  之前我们说到的都是java内置的异常,程序员也可以自己抛出一个异常。首先程序员需要先定义一个异常子类继承Exception 然后使用 throw 关键字抛出这个异常。

  throw 异常之后执行流会立即停止,程序会在最近的try块中查找符合条件的catch语句块。如果没有找到合适的语句块,则由运行时系统默认的异常处理进行处理。

  

public class TestException {    public static void main(String[] args) {        try {            throw new MyException();        }catch (MyException e) {            System.out.println("抛出一个异常 "+e);        }    }}class MyException extends Exception{    @Override    public String toString() {        // TODO Auto-generated method stub        return "自己定义的异常继承Exception /"+super.toString();    }}//抛出一个异常 自己定义的异常继承Exception /com.xiaobai.exception.MyException

7.throws 关键字

  有一些方法的异常我们知道可能会发生但是我们并不能进行处理,只能交给该方法的调用者处理。这时我们就要声明该方法可能会发生的异常。

  除Error和RuntimeException及其子类类型之外,其他异常类型是必须要被声明的。如果不这么做就会产生运行时错误。

  使用方式 : 在方法声明之后语句块之前添加throws关键字,并指明异常列表 (如果有多个,逗号分割)

public class TestException {    public static void main(String[] args) {        try {            doSomeThing();        }catch (Exception e) {            System.out.println("发生异常 "+e );        }                System.out.println("捕获异常之后继续执行");    }        static void doSomeThing() throws ArithmeticException,ArrayIndexOutOfBoundsException{        int[] arr = new int[5];        arr[3] = 5/0;        arr[10] = 6;    }}

8.finally

  对于早期的java来说,一旦发生异常,由于try中的语句没有执行完毕,有可能占用的一些资源(如文件等)没有被释放,那么finally就可以用来做这些事。

  finally块中的语句是指无论程序是否发生异常,都要执行的语句。如果不发生异常,程序执行完毕try后执行finally语句块;如果发生异常,程序则从try中发生异常的语句直接进入catch,当执行完catch后执行finally语句。

  注意:如果方法在try/catch语句中返回调用者(不论是使用了return还是未经捕获异常还是其他情况),都会在返回语句执行之前执行finally语句块。

  几个例子:

    1.正常返回执行finally:(不发生异常)

      

public class TestException {    public static void main(String[] args) {        doSomeThing();    }        static void doSomeThing(){        try {            System.out.println("这里是try");        }catch (Exception e) {            System.out.println("发生异常 "+e );        }finally {            System.out.println("执行finally");        }        System.out.println("这是try-catch-finally 之后");    }}//这里是try//执行finally//这是try-catch-finally 之后

 

 

 

    2. try中返回会先执行finally

    

public class TestException {    public static void main(String[] args) {        doSomeThing();    }        static void doSomeThing(){        try {            System.out.println("这里是try");            return;        }catch (Exception e) {            System.out.println("发生异常 "+e );        }finally {            System.out.println("执行finally");        }        System.out.println("这是try-catch-finally 之后");    }}//这里是try//执行finally

    3.catch到异常,返回之前执行finally

    

public class TestException {    public static void main(String[] args) {        doSomeThing();    }        static void doSomeThing(){        try {            System.out.println("这里是try");            int a = 1/0;        }catch (Exception e) {            System.out.println("发生异常 "+e );            return ;        }finally {            System.out.println("执行finally");        }        System.out.println("这是try-catch-finally 之后");    }}//这里是try//发生异常 java.lang.ArithmeticException: / by zero//执行finally

9.java中常用的内置异常

  9.1 未经检查异常

    RuntimeException异常类及其子类异常,在所有方法的throws列表中不用包含这些异常,同时编译器也不检查方法是否抛出或者处理这些异常,称作未经检查异常。

    

   9.2 检查异常

     如果方法可能产生一个或几个异常,如果方法本身不进行处理,则必须用过throws关键字抛出该异常,称为检查异常(编译器会进行检查)

    

 

转载于:https://www.cnblogs.com/xiaobai1202/p/10848689.html

你可能感兴趣的文章
windows下两个无线网卡 一个内网 一个外网
查看>>
tcp nat 负载均衡
查看>>
起点,游戏开发的梦想与技能点
查看>>
MPLS 流量工程的配置与各大属性调整详解
查看>>
107个常用Javascript语句
查看>>
我的友情链接
查看>>
Dataram_RAMDisk_v4_0_0安装和配置
查看>>
在window XP下使用vsphere client 5.5 访问vCenter 或者 ESXi5.5 连接错误
查看>>
35 个超棒的 Coming Soon 页面设计案例
查看>>
C语言第四天(位运算)
查看>>
硬RAID可以为NVMe SSD数据可靠性保驾护航吗?
查看>>
iPad 2 移植Siri 新手完全教程 适用所有越狱设备
查看>>
编程题:用函数实现,用户输入年月日,来计算出该日期为当年第几天?
查看>>
Pro Android学习笔记(十一):了解Intent(中)
查看>>
小程序混合框架HERA1.1.0发布
查看>>
linux下svn+rsync+inotify实现代码自动同步
查看>>
MYSQL主从+amoeba读写分离(一)
查看>>
tomcat并发量和内存的关系
查看>>
J2EE操作系统调优
查看>>
linux服务器校验时间
查看>>