Java中的异常机制

1.异常的定义:

       异常(又称为例外)是程序中的一些错误,但并不是所有的错误都是异常,并且错误有的时候是可以避免的。比如说,在编写代码的时候少了一个分号,那么运行出来结果提示是:java.lang.Error;或者在程序里出现(10/0)这种运算,因为在做除法的时候分母为0,则会抛出java.lang.ArithmrticException的异常。

2.异常的类型:

     (1)异常【非致命性的】:通过某种修正后程序还能正常执行。

            a)受查性异常:最具代表的受查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如:要打开一个不存在的文件时,一个异常就发生了,这异常在编译的时候不能被简单的忽略。

           b)运行时异常:运行时异常是可以被程序员避免的异常。与检查性异常性异常相反,运行时异常可以在编译的时候被忽略。例如:数组越界、除零等等。

    (2)错误【是致命性的】:错误就不是异常,而是脱离程序员控制的问题,是程序无法处理的错误,这些错误标识故障发生于虚拟机自身或者发生在虚拟机试图执行应用时,一般不需要程序处理。

3.异常类和错误类的层次结构图

4.常见的受查性异常类和非受查性异常类:

  (1)常见的受查性异常类:

 (2)常见的非受查性异常类:

5.异常捕获的格式:

(1)使用try和catch关键字可以捕获异常。

        try/catch代码块放在异常可能发生的地方。try/catch代码块中的代码称为保护代码,使用try/catch的语法如下:

    catch语句包含要捕获的异常类型的声明 。当保护代码块中发生一个异常时,try后面的catch块就会被检查

举个栗子:

public class TestException {
    public static void main(String[] args) {
        System.out.println("数学计算开始之前");
        
            System.out.println("进行计算中:"+10/0);

        System.out.println("数学计算已完成");
    }
}

程序运行结果:

修改之后:

public class TestException {
    public static void main(String[] args) {
        System.out.println("数学计算开始之前");
        try{
            System.out.println("进行计算中:"+10/0);
        }catch(ArithmeticException e){
            System.out.println("异常被处理了");
        }
        System.out.println("数学计算已完成");
    }
}

运行结果截图:

 

     上面的代码虽然进行了异常处理,但是我们并不知道产生了什么样的异常,所以为了明确的取得异常信息,可以直接输出异常类对象,或者调用所有异常类中提供的printStackTrace()方法进行完整信息的输出。

代码如下:

public class TestException {
    public static void main(String[] args) {
        System.out.println("数学计算开始之前");
        try {
            System.out.println("进行计算中:" + 10 / 0);

        }catch (ArithmeticException e){
            e.printStackTrace();
        }
        System.out.println("数学计算已完成");
    }
}

 程序运行结果:

由图可见,这段程序的异常信息是除零错误。

(2)使用 try...catch...finally进行处理

        finally关键字用来创建在 try 代码块后面执行的代码块,无论程序是否发生异常,finally代码块中的代码总会被执行,在finally代码块中,可以运行清理类型等收尾善后性质的语句,finally代码块出现在catch代码块之后语法如下:

 举个栗子:【代码如下】

public class TestException{
    public static void main(String[] args) {
        int []a=new int[2];
        try{
            System.out.println("Access element three :"+a[3]);
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println("异常信息为:"+e);
        }finally {
            a[0]=12;
            System.out.println("数组第一个元素为:"+a[0]);
            System.out.println("finally语句执行完成!");
        }
    }
}

运行结果:

 (3)多重捕获块:【即一个try后边跟随多个catch代码块的情况,语法如下:】

       执行步骤为:如果保护代码中发生异常,异常被抛给第一个catch块,如果抛出异常的类型与第一个catch语句里的异常类型匹配,那么该异常就在这里被捕获,否则就将它传给第二个人catch块,以此类推,直到异常被捕获或者通过所有的catch块。

   举个例子:

   

public class TestException{
    public static void main(String[] args) {
        System.out.println("数学开始计算之前");
        try{
            int x=Integer.parseInt(args[0]);
            int y=Integer.parseInt(args[1]);
            System.out.println("进行数学计算:"+x/y);
        }catch (ArithmeticException e){
            e.printStackTrace();
        }catch(NumberFormatException e){
            e.printStackTrace();
        }catch(ArrayIndexOutOfBoundsException e){
            e.printStackTrace();
        }finally {
            System.out.println("finally语句执行完成");
        }
        System.out.println("计算已经结束");
    }
}

运行结果:

 

 注意:

        a) catch不能独立于try 存在;

        b) 在 try/catch 后面添加finally块并非强制性要求的;

        c)  try 代码块后不能既没有catch 块也没有finally块;

        d)try,catch,finally 块之间不能添加任何代码。

(4)throws和throw关键字

         i)throws用在方法上,在进行方法定义的时候,如果要告诉调用者本方法可能产生哪些异常,就可以使用throws方法进行声明,也就是,如果该方法出现问题不希望进行处理,就使用throws抛出:

    a. 举个栗子:

public class TestException{
    public static void main(String[] args)  {
        try{
            System.out.println(caculate(10,0));
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static int caculate(int x,int y) throws Exception{
        return x/y;
    }
}

运行结果:

      此时main方调用了throws声明的方法,那么在调用的时候就要进行异常捕获,该方法有可能产生异常,所以必须按照异常处理格式进行处理。 

      b.主方法也属于方法,所以主方法上也可以使用throws关键字,这个时候如果产生异常,就会交给JVM来进行处理,对上面的例子进行改造为:

public class TestException{
    public static void main(String[] args)throws Exception  {
        try{
            System.out.println(caculate(10,0));
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static int caculate(int x,int y) throws Exception{
        return x/y;
    }
}


运行结果:

ii)throw 关键字:throw关键字用于方法内部,是直接编写在语句之中的,表示人为的进行异常抛出

     举个例子:【对上述代码进行改造】

public class TestException{
    public static void main(String[] args)  {
        try{
            System.out.println(caculate(10,0));
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static int caculate(int x,int y) throws Exception{
        int result=0;
        System.out.println("计算开始之前");
        try{
            result=x/y;
        }catch(Exception e){
            throw  e;//将异常抛出去
        }finally {
            System.out.println("计算结束");
        }
        return result;
    }
}


  运行结果:

6.Error与Exception的异同:

   (1)相同之处:Error类和Exception类都是继承自Throwable类

   (2)不同之处:

          Error是由JVM底层引起的错误,是程序员不能改变和处理的,是在编译时出现的错误,是不可捕获的,只能通过修改程序才能修正。如:系统崩溃,虚拟机错误,内存空间不足,栈溢出等。

          Exception表示程序可以处理的异常,可以捕获并且可能恢复。遇到这类异常,应该尽可能的处理异常,是程序恢复运行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值