时间: 2021-06-28 10:57:27
Java Error能不能捕获这个问题,之前从别人的博客看到过,然后自己也实验过,其实Error和Exception一样是可以捕获的。但是前些时候,又开始和同事讨论了起来,相比之前别人的文章,只是验证可以捕获,想加入点不同的东西。所以写下这篇文章。
首先下面的代码就是出现异常并捕获的代码。
private static void testCatchError() { try { throw new Error("An error occurs here"); } catch (Exception e) { System.out.println("catched as Exception"); e.printStackTrace(); } catch (Error e) { System.out.println("catched as Error"); e.printStackTrace(); } catch (Throwable t) { System.out.println("catched as Throwable"); t.printStackTrace(); } System.out.println("reach the end of the method"); }
运行这个方法,日志出现了。
java.lang.Error: An error occurs here at ps.androidyue.catcherror.MainRoot.testCatchError(MainRoot.java:10) at ps.androidyue.catcherror.MainRoot.main(MainRoot.java:5) catched as Error reach the end of the method
从上面的日志我们可以很明确的分析出来,我们throw出的Error对象,没有经过Exception的catch,而是进入了Error的catch并成功捕获,进而可以向下执行到末尾的输出。
那么Error比Exception的层级高还是两者并列?后面的Throwable又是什么呢
首先我们了解一下Throwable,从javadoc可以看出是VM可以抛出的对象实例的超类,Error和Exception是并列的关系。比如我们常常调用的exception.printStackTrace() 就是Throwable中的。
/** * The superclass of all classes which can be thrown by the VM. The * two direct subclasses are recoverable exceptions ({@code Exception}) and * unrecoverable errors ({@code Error}). This class provides common methods for * accessing a string message which provides extra information about the * circumstances in which the {@code Throwable} was created (basically an error * message in most cases), and for saving a stack trace (that is, a record of * the call stack at a particular point in time) which can be printed later. * <p> * A {@code Throwable} can also include a cause, which is a nested {@code * Throwable} that represents the original problem that led to this {@code * Throwable}. It is often used for wrapping various types of errors into a * common {@code Throwable} without losing the detailed original error * information. When printing the stack trace, the trace of the cause is * included. * * @see Error * @see Exception * @see RuntimeException */ public class Throwable implements java.io.Serializable { //code goes here }
Exception的部分代码
/** * {@code Exception} is the superclass of all classes that represent recoverable * exceptions. When exceptions are thrown, they may be caught by application * code. * * @see Throwable * @see Error * @see RuntimeException */ public class Exception extends Throwable { //code goes here }
Error的部分代码
/** * {@code Error} is the superclass of all classes that represent unrecoverable * errors. When errors are thrown, they should not be caught by application * code. * * @see Throwable * @see Exception * @see RuntimeException */ public class Error extends Throwable { //code goes here }
那么我们可以使用try-catch捕获异常,错误,亦或者使用从更大层面捕获Throwable,这一点是不可取的。我们使用try-catch捕获异常是可以,因为这些异常一般是Application code产生的。但是像错误不应该被程序代码捕获。极个别的除外,比如说OutOfMemoryError.
那么为什么有点异常需要强制使用try-catch,有的则不需要?
java中有两种大类型的异常,一种是RuntimeException,另一种是非RuntimeException。
RuntimeException是unchecked的异常,不需要使用try-catch
常见的RuntimeException有NullPointerException等
而非RuntimeException是checked异常,需要使用try-catch 来check
还有一个问题,就是关于Exception是recoverable,而Error是unrecoverable这个目前不是很清楚,下来研究另文说明。