当前位置: 首页 > 后端技术 > Java

【Java面试指南】ExceptionErrorThrowable你分得清吗?

时间:2023-04-01 14:14:31 Java

阅读本文之前,如果让你描述ExceptionErrorThrowable的区别,你能回答吗?你的反应是不是像下面这样?当你写代码的时候,你会经常尝试catch(Exception),你会在日志中看到OutOfMemoryErrorThrowable。这似乎并不常见,但您可能听说过。1.ExceptionErrorThrowable的关系直接看下图,可以看出三者的关系:Throwable是Error和Exception的父类。异常是程序正常运行中的正常情况,应该被捕获和处理。它分为已检查异常和未检查异常。检查异常是编译时检查的一部分,必须明确捕获。如果有一个方法抛出异常,那么调用这个函数必须经过catch处理或者再次抛出,交给下一层处理。未检查异常一般是指运行时异常(RuntimeException),类似于ArrayIndexOutOfBoundsException、ArithmeticException等,一般可以通过代码逻辑来避免,看情况是否被捕获。在正常情况下一般不太可能发生错误。大多数错误都会导致程序处于不可恢复的状态,所以没有必要捕获它们。比如OutOfMemoryError。2.比较一个Error和Exception面试的时候你可能会被问到:NoClassDefFoundError和ClassNotFoundException有什么区别?首先我们来看这两个名字,一个是Error,一个是Exception。从上面的介绍和下面的继承图我们可以得到:ClassNotFoundException应该是编码时要捕获的异常,NoClassDefFoundError是编译通过的,但是运行时产生的。主要问题。更进一步:ClassNotFoundException是在运行时动态加载类时出现的问题。比如用Class.forName动态加载一个类,如果不显示catch处理,ide会给你一个提示,是不会通过编译的。//错误的写法publicvoidexcept(){Class.forName("com.test.aaa");}//正确的写法publicvoidexcept(){try{Class.forName("com.test.aaa");}catch(ClassNotFoundExceptione){//throworlogthrownewRuntimeException(e);//log.error("ClassNotFoundException:",e);}}NoClassDefFoundError在编译时没有问题,但是在运行时找不到新的实例。比如在一个类中引用另一个类的函数,编译后删除另一个类的class文件:publicclassMain{publicstaticvoidmain(String[]args){System.out.println("Helloworld!”);我的打印.printName();}}publicclassMyPrint{publicstaticvoidprintName(){System.out.println("我叫张三");}}用javac编译,然后删除MyPrint.class$treecom└──shuofxz├──Main.class├──Main.java├──MyPrint.class#删除这个文件└──MyPrint.java执行程序,你会看到NoClassDefFoundError,它是由ClassNotFoundException引起的。线程“main”中的异常java.lang.NoClassDefFoundError:com/shuofxz/MyPrintatcom.shuofxz.Main.main(Main.java:6)Causedby:java.lang.ClassNotFoundException:com.shuofxz.MyPrintatjava.net.URLClassLoader.findClass(URLClassLoader.java:387)在java.lang.ClassLoader.loadClass(ClassLoader.java:419)在sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)在java.lang.ClassLoader。loadClass(ClassLoader.java:352)...1more3.捕获异常代码的常见问题1)下面的代码有什么问题?try{//业务代码//...Thread.sleep(1000L);}catch(Exceptione){}捕获过于笼统的异常Exception,应该改为对应的InterruptedException。这样做的目的是因为:第一,方便阅读代码,知道具体可能会出现什么异常;其次,它不会捕获意外异常。捕获到异常后不要什么都不做(将异常活吞)。这是给自己挖坑,然后程序遇到问题,你就很难定位到这里。2)再看下面一个,添加了异常打印逻辑,有没有问题?try{//业务代码//...}catch(IOExceptione){e.printStackTrace();}自娱自乐是可以的,但不要放在生产环境中。因为e.printStackTrace()的功能是:将这个throwable及其回溯打印到标准错误流。你很难说出它输出到哪里。应该使用成熟的日志记录工具,例如Slf4j。3)看下面:try{//业务逻辑A//业务逻辑B//业务逻辑C//...}catch(Exceptione){log.error("haveexception",e);}cannot因为怕丢失异常捕获,所以把一大段代码放到了一个try-catch模块中。try-catch代码段会产生额外的性能开销,往往会影响JVM对代码的优化。4)前面我们介绍了Exception、Error、Throwable。为什么在代码中经常看到catchXXException,却很少看到catchXXError或者catchThrowable?Exception是你应该注意处理的异常。这个异常处理后,程序仍然可以正常运行。Error是一个大问题,会导致程序直接崩溃。抓到也没用。节目很难再“直播”了。至于Throwable,首先它应该不是这么宽泛的问题(比捕获Exception还严重),其次它包含Error,这不是你应该处理的。因此,除非您确切地知道自己在做什么,否则不要捕获Error和Throwable。3.总结本文介绍了ExceptionErrorThrowable的区别,并给出了相关的例子来帮助理解。回到开头的问题:《描述ExceptionErrorThrowable的区别》你知道吗?