狂刷牛客的Java专题,我总结出易错的异常题型

本文详细探讨了Java异常处理中try-catch-finally块与return语句的执行顺序,强调了finally块的执行优先级。无论是否抛出异常,finally块总会被执行。在return语句与finally块共存时,finally块的return会覆盖try或catch中的return。此外,还总结了Java异常的分类,包括编译时异常和运行时异常,以及处理异常的最佳实践。
摘要由CSDN通过智能技术生成

异常

异常是指程序运行时(非编译)所发生的非正常情况或错误,当程序违反了语言规则,jvm就会将出现的错误表示一个异常抛出。异常也是java 的对象,定义了基类 java.lang.throwable作为异常父类。 这些异常类又包括error和exception。两大类

error类异常主要是运行时逻辑错误导致,一个正确程序中是不应该出现error的。当出现error一般jvm会终止。

exception表示可恢复异常,包括检查异常和运行时异常。

检查异常是最常见异常比如IO异常、SQL异常,都发生在**编译阶段。**这类通过try…catch捕捉 。

运行时异常,编译器没有强制对其进行捕捉和处理。一般都会把异常向上抛出,直到遇到处理代码位置,若没有处理块就会抛到最上层,多线程用thread的run()抛出,单线程用main()抛出。常见的运行异常包括、空指针异常、类型转换异常、数组越界异常、数组存储异常、缓冲区溢出异常、算术异常等。

题型一:try块中抛出异常,try、catch和finally中都有return语句

public static int WithException(){
   int i=10;
   try{
        System.out.println("i in try block is : "+i);
        i = i/0;
        return --i;
    }
   catch(Exception e){
        System.out.println("i in catch - form try block is : "+i);
        --i;
        System.out.println("i in catch block is : "+i);
        return --i;
    }
   finally{
        System.out.println("i in finally - from try or catch block is--"+i);
        --i;
        System.out.println("i in finally block is--"+i);
        return --i;
    }
}

执行顺序:

抛出异常后,执行catch块,在catch块的return的- -i执行完后,并不直接返回而是执行finally,因finally中有return语句,所以,执行,返回结果6。

i in try block is : 10     
i in catch - form try block is : 10     
i in catch block is : 9     
i in finally - from try or catch block is--8     
i in finally block is--7     
6     

结论:

try块中抛出异常,try、catch和finally中都有return语句,返回值是finally中的return。

题型二:如果try,finally语句里均有return,忽略try的return,而使用finally的return.

在这里插入图片描述

如果finally块中有return语句的话,它将覆盖掉函数中其他return语句。

在这里插入图片描述

结果30

题型三:

以下代码段执行后的输出结果为:

public class Test {
public static void main(String[] args) {
System.out.println(test());

}
private static int test() {
  int temp = 1;
  try {
    System.out.println(temp);
    return ++temp;
  } catch (Exception e) {
      System.out.println(temp);
      return ++temp;
  } finally {
      ++temp;
      System.out.println(temp);
   }
}
}

执行顺序为:

输出try里面的初始temp:1;

temp=2;

保存return里面temp的值:2;

执行finally的语句temp:3,输出temp:3;

返回try中的return语句,返回存在里面的temp的值:2;

输出temp:2。

小结:
如果try语句里有return,返回的是try语句块中变量值。
详细执行过程如下:

  1. 如果有返回值,就把返回值保存到局部变量中;
  2. 执行jsr指令跳到finally语句里执行;
  3. 执行完finally语句后,返回之前保存在局部变量表里的值。

题型四:
下列输出结果为:

package Test;
public class Test {
    private static void test(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            try {
                if (arr[i] % 2 == 0) {
                    throw new NullPointerException();
                } else {
                    System.out.print(i);
                }
            } finally {
                System.out.print("e");
            }
        }
    }

    public static void main(String[]args) {
        try {
            test(new int[] {0, 1, 2, 3, 4, 5});
        } catch (Exception e) {
            System.out.print("E");
        }
    }

}

eE

这道主要是要知道调用的方法报异常前要先执行完finally代码块,还有没有catch语句对异常做出处理,所以异常会往上抛至调用处,中断test()方法的继续执行。试对比:

package Test;
public class Test {
    private static void test(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            try {
                if (arr[i] % 2 == 0) {
                    throw new NullPointerException();
                } else {
                    System.out.print(i);
                }
            } catch (NullPointerException e){
                System.out.print("catch!");
            }finally {
                System.out.println("e");
            }
        }
    }

    public static void main(String[]args) {
        try {
            test(new int[] {0, 1, 2, 3, 4, 5});
        } catch (Exception e) {
            System.out.print("E");
        }
    }

}

输出:

catch!finally
1finally
catch!finally
3finally
catch!finally
5finally

因为有catch代码块对异常做出相应处理,所以异常不会往上抛,故main方法中的catch代码块没有执行,另外,test()方法也不会中断,提前退出。

题型五:
在这里插入图片描述 1.执行foo(0)时,不满足try语句块中的if语句,所以不会抛出异常,执行finally语句

2.执行foo(1)时,满足try中的If语句,抛出异常,在catch中进行异常处理,虽然有return语句,但是finally中的内容必须执行,也就是说要先执行了finally才进行return操作,return后 output += “4”将不会再执行.

3423

一些易忽视的点:

throw new Exception(" ");

在这里插入图片描述

在这里插入图片描述

Java异常都继承自类Throwable,Throwable子类有Error和Exception,其中Exception又分为运行时异常和编译时异常。编译时异常是未雨绸缪性质的异常,是防范,需要显示处理。运行时异常是程序员问题造成,并不强制进行显示处理。

总体结论:

结论一:

return语句并不是函数的最终出口,如果有finally语句,这在return之后还会执行finally(return的值会暂存在栈里面,等待finally执行后再返回)
结论二:

finally里面不建议放return语句,根据需要,return语句可以放在try和catch里面和函数的最后。可行的做法有四:
(1)return语句只在函数最后出现一次。
(2)return语句仅在try和catch里面都出现。
(3)return语句仅在try和函数的最后都出现。
(4)return语句仅在catch和函数的最后都出现。

结论三:

catch可以省略,try的形式有三种:

try-catch

try-finally

try-catch-finally

catch和finally语句不能同时省略!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值