【Java面试指北】Exception Error Throwable 你分得清么?()

  本篇文章为你整理了【Java面试指北】Exception Error Throwable 你分得清么?()的详细内容,包含有 【Java面试指北】Exception Error Throwable 你分得清么?,希望能帮助你了解 【Java面试指北】Exception Error Throwable 你分得清么?。

   读本篇文章之前,如果让你叙述一下 Exception Error Throwable 的区别,你能回答出来么?

  你的反应是不是像下面一样呢?

  你在写代码时会经常 try catch(Exception)

  在 log 中会看到 OutOfMemoryError

  Throwable 似乎不常见,但也大概听说过

  
读本篇文章之前,如果让你叙述一下 Exception Error Throwable 的区别,你能回答出来么?
 

  你的反应是不是像下面一样呢?

  你在写代码时会经常 try catch(Exception)

  在 log 中会看到 OutOfMemoryError

  Throwable 似乎不常见,但也大概听说过

  一、Exception Error Throwable 关系

  直接看下图,展示了三者之间的关系:

  Throwable 是 Error 和 Exception 的父类。

  Exception是程序正常运行中可预料的正常情况,应该被捕获并进行处理。

  又分为可检查(checked)和不检查(unchecked)异常。

  可检查异常是在编译期检查的一部分,必须显示捕获处理。如有的方法 throw exception,那么调用该函数则必须 catch 处理或者再次 throw 出去交给下一层处理。

  不检查异常一般指运行时异常(RuntimeException),类似 ArrayIndexOutOfBoundsException、ArithmeticException等。一般可由代码逻辑避免,可看情况是否捕获。

  
Error 一般是正常情况下不太可能出现的,绝大部分 Error 会导致程序处于不可恢复的状态,所以也不必捕获。如 OutOfMemoryError。

  二、对比一个 Error 和 Exception

  你在面试中也许会被问到:

  NoClassDefFoundError 和 ClassNotFoundException 有什么区别?

  首先,我们看这俩名字,一个是 Error 另一个是 Exception,从上面的介绍以及看下面的继承图可以得到:ClassNotFoundException 应是编码时要被捕获的异常,NoClassDefFoundError 是编译通过了,但运行时产生的重大问题。
 

  进一步的:
 

  ClassNotFoundException 是运行中动态加载类时出现的问题。
 

  举例来说,使用 Class.forName 来动态加载一个类,如果你不显示的 catch 处理,ide 都会给你提示,并且也过不了编译。

  

// 错误写法

 

  public void except() {

   Class.forName("com.test.aaa");

  // 正确写法

  public void except() {

   try {

   Class.forName("com.test.aaa");

   } catch (ClassNotFoundException e) {

   // throw or log

   throw new RuntimeException(e);

   // log.error("ClassNotFoundException: ", e);

  

 

  NoClassDefFoundError 是编译时没问题,但运行时 new 实例找不到。
 

  比如在一个类中调用另一个类的方法,编译后把另一个类的 class 文件删掉:

  

public class Main {

 

   public static void main(String[] args) {

   System.out.println("Hello world!");

   MyPrint.printName();

  

 

  

public class MyPrint {

 

   public static void printName() {

   System.out.println("my name is zhangsan");

  

 

  使用 javac 编译,再删除 MyPrint.class

  

$ tree com

 

  └── shuofxz

   ├── Main.class

   ├── Main.java

   ├── MyPrint.class # 把这个文件删掉

   └── MyPrint.java

  

 

  执行程序,就会看到 NoClassDefFoundError,并且是由 ClassNotFoundException 引起的。

  

Exception in thread "main" java.lang.NoClassDefFoundError: com/shuofxz/MyPrint

 

   at com.shuofxz.Main.main(Main.java:6)

  Caused by: java.lang.ClassNotFoundException: com.shuofxz.MyPrint

   at java.net.URLClassLoader.findClass(URLClassLoader.java:387)

   at java.lang.ClassLoader.loadClass(ClassLoader.java:419)

   at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)

   at java.lang.ClassLoader.loadClass(ClassLoader.java:352)

   ... 1 more

  

 

  三、捕获异常代码常见问题

  一)看下面的代码有什么问题?

  

try {

 

   // 业务代码

   // ...

   Thread.sleep(1000L);

  } catch (Exception e) {

  

 

  捕获了过于通用的异常 Exception,应改为对应的 InterruptedException。这么做的目的是因为:第一方便阅读代码,知道可能会出现什么具体的异常;第二不捕获意料之外的异常。

  不要捕获异常之后啥都不做(生吞异常)。这就是给自己挖坑,之后程序遇到问题,你很难定位到这里。

  二)再看下面这个,增加了异常打印逻辑,还有什么问题不?

  

try {

 

   // 业务代码

   // …

  } catch (IOException e) {

   e.printStackTrace();

  

 

  自娱自乐是 ok 的,但不要放到生产环境中。因为 e.printStackTrace() 的功能是:Prints this throwable and its backtrace to the standard error stream。你很难判断它到底输出到哪里去了。

  应该用成熟的日志工具如 Slf4j 等。

  三)再来看下面的:

  

try {

 

   // 业务逻辑 A

   // 业务逻辑 B

   // 业务逻辑 C

   // ...

  } catch (Exception e) {

   log.error("have exception", e);

  

 

  不能因为怕丢失异常捕获,就把一大段代码都框到一个 try-catch 模块中。

  try-catch 代码段会产生额外的性能开销,它往往会影响 JVM 对代码进行优化。

  四)我们前面介绍了Exception、Error、Throwable,为什么代码中经常能看到 catch XXException,却几乎看不到 catch XXError 或 catch Throwable 呢?

  Exception 才是你应该关注处理的异常,这种异常处理后还可以使程序正常运行。

  Error 属于重大问题,是会使程序直接崩溃的,你捕获了也没什么用,很难让程序再「活」过来。

  至于 Throwable,首先不应该捕获这么宽泛的问题(比捕获 Exception 还严重),第二其中包含了 Error 也不是你应该处理的问题。

  因此,Error 和 Throwable 除非你明确知道你在干什么,否则不要捕获这两种。

  本篇介绍了 Exception Error Throwable 的区别,并给出了相关例子帮助理解。
 

  回到开头的问题:「叙述一下 Exception Error Throwable 的区别」你心里有数了么?

  以上就是【Java面试指北】Exception Error Throwable 你分得清么?()的详细内容,想要了解更多 【Java面试指北】Exception Error Throwable 你分得清么?的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: