在程序开发中,异常处理也是咱们常用到的模块,只是日常不多去深究异常模块的一些知识点。好比,try-catch 处理要遵循的原则是什么,finally 为何老是能执行,try-catch 为何比较消耗程序的执行性能等问题,咱们本讲内容都会给出相应的答案,固然还有面试中常常被问到的异常模块的一些面试题,也是咱们本篇要讲解的重点内容。java
先来看看异常处理的语法格式:面试
try{ ... } catch(Exception e){ ... } finally{ ... }
其中,数据库
异常处理的基本使用,具体能够参考下面的代码段:json
try { int i = 10 / 0; } catch (ArithmeticException e) { System.out.println(e); } finally { System.out.println("finally"); }
多 catch 的使用,具体能够参考下面的代码段:数组
try { int i = Integer.parseInt(null); } catch (ArithmeticException ae) { System.out.println("ArithmeticException"); } catch (NullPointerException ne) { System.out.println("NullPointerException"); } catch (Exception e) { System.out.println("Exception"); }
须要注意的是 Java 虚拟机会从上往下匹配错误类型,所以前面的 catch 异常类型不能包含后面的异常类型。好比上面的代码若是把 Exception 放在最前面编译器就会报错,具体能够参考下面的图片。性能
随着 Java 语言的发展,JDK 7 的时候引入了一些更加便利的特性,用来更方便的处理异常信息,如 try-with-resources 和 multiple catch,具体能够参考下面的代码段:优化
try (FileReader fileReader = new FileReader(""); FileWriter fileWriter = new FileWriter("")) { // try-with-resources System.out.println("try"); } catch (IOException | NullPointerException e) { // multiple catch System.out.println(e); }
先来看下面这段代码,有没有发现一些问题?spa
try { // ... int i = Integer.parseInt(null); } catch (Exception e) { }
以上的这段代码,看似“正常”,却违背了异常处理的两个基本原则:线程
异常处理当然好用,但必定不要滥用,好比下面的代码片断:指针
// 使用 com.alibaba.fastjson JSONArray array = new JSONArray(); String jsonStr = "{'name':'laowang'}"; try { array = JSONArray.parseArray(jsonStr); } catch (Exception e) { array.add(JSONObject.parse(jsonStr)); } System.out.println(array.size());
这段代码是借助了 try-catch 去处理程序的业务逻辑,一般是不可取的,缘由包括下列两个方面。
以上使用 try-catch 处理业务的代码,能够修改成下列代码:
// 使用 com.alibaba.fastjson JSONArray array = new JSONArray(); String jsonStr = "{'name':'laowang'}"; if (null != jsonStr && !jsonStr.equals("")) { String firstChar = jsonStr.substring(0, 1); if (firstChar.equals("{")) { array.add(JSONObject.parse(jsonStr)); } else if (firstChar.equals("[")) { array = JSONArray.parseArray(jsonStr); } } System.out.println(array.size());
答:try 不能单独使用,不然就失去了 try 的意义和价值。
try { int i = 10 / 0; } catch { System.out.println("last"); }
答:不能正常运行,catch 后必须包含异常信息,如 catch (Exception e)。
try { int i = 10 / 0; } finally { System.out.println("last"); }
答:能够正常运行。
try { int i = 10 / 0; System.out.println("try"); } catch (Exception e) { int j = 2 / 0; System.out.println("catch"); } finally { System.out.println("finally"); } System.out.println("main");
答:程序会打印出 finally 以后抛出异常并终止运行。
try { System.out.println("try"); } catch (Exception e) { System.out.println("catch"); } finally { int k = 3 / 0; System.out.println("finally"); } System.out.println("main");
答:程序在输出 try 以后抛出异常并终止运行,不会再执行 finally 异常以后的代码。
答:常见的运行时异常以下:
试图经过字符串来加载某个类时引起的异常;
答:Exception 和 Error 都属于 Throwable 的子类,在 Java 中只有 Throwable 及其之类才能被捕获或抛出,它们的区别以下:
答:它们的区别以下:
答:Integer.parseInt(null) 和 Double.parseDouble(null) 抛出的异常类型不同,以下所示:
至于为何会产生不一样的异常,其实没有特殊的缘由,主要是因为这两个功能是不一样人开发的,于是就产生了两种不一样的异常信息。
答:这个问题要从 JVM(Java 虚拟机)层面找答案了。首先 Java 虚拟机在构造异常实例的时候须要生成该异常的栈轨迹,这个操做会逐一访问当前线程的栈帧,而且记录下各类调试信息,包括栈帧所指向方法的名字,方法所在的类名、文件名,以及在代码中的第几行触发该异常等信息,这就是使用异常捕获耗时的主要缘由了。
答:常见的 OOM 缘由有如下几个:
public static int getNumber() { try { int number = 0 / 1; return 2; } finally { return 3; } }
A:0
B:2
C:3
D:1
答:3
题目解析:程序最后必定会执行 finally 里的代码,会把以前的结果覆盖为 3。
答:finally、finalize 的区别以下:
答:finally 总会被执行,都是编译器的做用,由于编译器在编译 Java 代码时,会复制 finally 代码块的内容,而后分别放在 try-catch 代码块全部的正常执行路径及异常执行路径的出口中,这样 finally 才会无论发生什么状况都会执行。
欢迎关注个人公众号,回复关键字“Java” ,将会有大礼相送!!! 祝各位面试成功!!!