java异常处理

异常的概念

异常(Exception)指的是程序运行中出现非正常情况。在程序运行过程中,任何中断正常程序流程的情况都是错误或异常。在实际应用中,可能存在大量的未知问题,而异常机制可以帮助我们更好的调试程序,解决问题。

常见的问题有:

想打开的文件不存在;
网络连接中断;
操作数超出预定范围;(如除数为0)
数组元素下标越界。

Java程序可以用代码来处理异常并继续执行程序,而不是让程序中断。

Java对异常的处理是面向对象的。它提供了异常处理类,专门用于处理程序运行期间的错误。每当Java程序运行过程发生一个可识别的运行错误时,即该错误有一个异常类与之相对应时,系统会产生该异常类的一个相应对象,即产生一个异常。
Exception就是一个描述异常情况的类(这个类具有存储问题信息的成员域)。当出现异常时,一个Exception对象就产生了,并被放到产生这个异常的方法里。
异常对象一旦产生,系统中就一定有相应的机制来处理它,确保不会产生死机、死循环或其他对操作系统的损害,从而保证了整个程序运行的安全性。

java中的异常类

异常总是标准类Throwable的一些子类的对象。Throwable类的两个直接子类,即Error类和Exception类,覆盖了所有的标准异常。

同其他的类一样,Exception类有自己的方法和属性。它的构造方法有两个:

public Exception();
public Exception(String s);

第二个构造方法可以接受字符串s参数传入的信息,该信息通常是对该异常所对应的错误的描述。

Exception类还从父类Throwable那里继承了若干方法,其中常用的有:

public String toString() 
    返回描述当前Exception类信息的字符串。
public void printStackTrace() 
    打印当前异常对象的堆栈轨迹,即程序先后调用执行了哪些对象或类的方法,使运行过程产生了这个异常对象。

Java 提供了两种Exception 的模式,一种是执行的时候所产生的Exception (Runtime Exception),另外一种则是受控制的Exception (Checked Exception)。
所有的Checked Exception 均从java.lang.Exception 继承而来;
而Runtime Exception 则继承java.lang.RuntimeException
(实际上java.lang.RuntimeException 的上一层也是java.lang.Exception)。

RuntimeException异常通常由代码中的严重错误产生,编译器允许忽略它们。
RuntimeException 的子类有:

ArithmeticException,出现非法算术操作
IndexOutOfBoundsException,试图使用一个越界的索引来引用一个对象
NullPointerException,对一个值为null的对象进行操作
IllegalArgumentException-实参与形参的类型不符

对于从Exception类派生出来的所有其他类,编译器都会检查是否已经在可能抛出异常的方法中进行异常处理,或者已经指出该方法会抛出这样一个异常。

Java中异常处理机制可以概括为以下几个过程:

①在Java程序的执行过程中,如果出现异常,则自动生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出异常。抛出异常也可以由程序来强制进行。
②当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕捉异常。
③如果Java运行时系统找不到可以捕获异常的方法,则将终止,相应的Java程序也将退出。
Java的异常处理是通过5个关键字来实现的:try,catch,throw,throws和finally。

Java通过使用try―catch―finally语句来捕捉一个或多个异常,基本格式为:

try{
        语句
}catch(异常类名1 异常对象名){
        异常处理代码
}catch(异常类名2 异常对象名){
       异常处理代码
}finally{
       语句
}

其中一条try语句可以跟多个catch语句和一个finally语句,但try语句不能单独出现,必须至少有一个catch语句或finally。

try语句

try语句用大括号{ }指定了一段代码,该代码可能会抛出一个或多个异常。若try块中出现异常,则控制转向下面的异常处理部分,然后执行后续语句,若try块中没有异常,则try块执行完后,控制转向后续语句。

catch语句

catch语句的参数类似于方法的声明,包括一个异常类型和一个异常对象。异常类型必须是Throwsable的子类,它指明catch语句所处理的异常类型,异常对象则由运行时系统在try所指定的代码块中生成并捕获,大括号中包含对象的处理,其中可以调用对象的方法。

catch语句可以有多个,分别处理不同类型的异常。Java运行时系统从上到下依次对每个catch语句处理的异常类型进行检查,直到找到类型匹配的catch语句为止。这里,类型匹配是指catch所处理的异常类型与生成的异常对象完全一致或者是它的父类。因此,catch语句的排列顺序应该是从特殊到一般。
也可以用一个catch语句处理多个异常类型,这时,它的异常类型应该是这多个异常类型的父类。程序设计中要根据具体的情况来选择catch语句的异常处理类型。

finally语句

finally语句是可选的,如在try-catch之后接上finally语句,则无论有无异常,最后都必须执行finally块中的语句。finally语句提供了一个统一的出口,通常可以进行资源的清理工作,如关闭打开的文件等。

示例程序:

public class Test {
    public static void main(String arg[]) {
        int i = 0;
        String s[] = { "ok!", "ok!!", "ok!!!" };
        while (i < 4) {
            try {
                System.out.println(s[i]);
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("数组下标越界!");
            } finally {
                System.out.println("finally被执行!");
            }

            i++;
        }
    }
}

输出:
ok!
finally被执行!
ok!!
finally被执行!
ok!!!
finally被执行!
数组下标越界!
finally被执行!

抛出异常

在捕捉一个异常前,必须有一段Java代码生成一个异常对象并把它抛出。抛出的代码可以是自己编写的Java程序,也可以是类库中的某个类,或者是Java运行时系统。它们都是通过throw语句来实现的。

throw语句的格式为:
        throw ThrowableObject;

示例:

class Test {
    static int div(int a, int b) {
        try {
            if (b == 0) {
                ArithmeticException e = new ArithmeticException("除数不能为0");
                throw e;//抛出异常
            }
        } catch (ArithmeticException e) {
            System.out.println(e.getMessage());
            return 0;
        }
        return a / b;
    }

    public static void main(String arg[]) {
        int m = 0;
        m = div(4, 0);
        System.out.println(m);
    }
}

输出:
除数不能为0
0

声明异常

在方法中可以使用try-catch-finally来处理方法中抛出的异常。在有些情况下,方法并不需要处理它所生成的异常,而是由调用它的方法来处理这些异常,这时就要用到throws子句,它包含在方法的声明中。
其格式如下:

  返回类型 方法名(参数列表) throws 异常列表

其中,在异常列表中可以声明多个异常,用逗号隔开。

示例:

public class Test {
    static int div(int a, int b) throws ArithmeticException {//声明异常
        if (b == 0) {
            ArithmeticException e = new ArithmeticException("除数不能为0");
            throw e;
        }
        return a / b;
    }

    public static void main(String arg[]) {
        int m = 0;
        try {
            m = div(4, 0);
            System.out.println(m);
        } catch (ArithmeticException e) {
            System.out.println(e.getMessage());
        }

    }
}

输出:
除数不能为0

创建自定义异常

Java类库中定义的异常主要用来处理系统可以预见的、比较常见的运行错误。如果某个应用程序有特殊的要求,则可能出现系统不能识别的运行错误。这时,用户就需要自己创建异常和异常类,使系统能够识别这种错误并进行处理。

①声明一个新的异常类,使之继承Exception、Exception类的子类或用户自定义的异常类。
    格式如下:
        class 自定义异常类名 extends 父异常类名{
                类体
        }
②为新的异常类定义属性和方法,或重载父类的属性和方法,使之能够体现出程序中出现的这种异常信息。
③抛出用户自定义的异常。用户自定义的异常不可能依靠系统自动抛出,而必须通过throw抛出。

范例:

计算0-100之间的两个整数之和
package sxx;

class NumberRangeException extends Exception{//自定义异常类型
    public NumberRangeException(){
        super();//调用父类的构造方法
    }
    public NumberRangeException(String msg){
        super(msg);
    }
}

class M{
public static String sum(String s1,String s2) throws NumberRangeException{
        int a=Integer.parseInt(s1);
        int b=Integer.parseInt(s2);
        if((a<0)||(a>100)||(b<0)||(b>100)){
            throw (new NumberRangeException("输入的数字超出范围!"));
        }
        return Integer.toString(a+b);
    }
}

public class Test{
    public static void main(String args[]){
        try{
            String s=M.sum("1", "2", "3");
            System.out.println(s);
        }catch(NumberRangeException e){
            System.out.println("错误:"+e.getMessage());
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

结果:
java sxx.Test -2 5

输出: 
错误:输入的数字超出范围!
NumberRangeException: 输入的数字超出范围!
        at M.sum(test.java:15)
        at Test.main(test.java:24)

范例二:

package test;

    class NumberRangeException extends Exception{//自定义异常类型
        public NumberRangeException(){
            super();//调用父类的构造方法
        }
        public NumberRangeException(String msg){
            super(msg);
        }
    }

    class M{
        public static String sum(String ...value) throws NumberRangeException{//声明异常,接收不定参数
            int a[] = new int[100];
            int sum = 0;
            for(int i = 0; i < value.length; i++) {
                a[i] = Integer.parseInt(value[i]);
                if(a[i] > 100 || a[i] < 0)
                    throw(new NumberRangeException("输入的数字超出范围!"));
                sum += a[i];
            }
            return Integer.toString(sum);
        }
    }
    public class Test{
        public static void main(String args[]){
            try{
                String s=M.sum("1", "2", "3");
                System.out.println(s);
            }catch(NumberRangeException e){
                System.out.println("错误:"+e.getMessage());
                e.printStackTrace();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    输出:
    6
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值