Java中Error捕获深入

  时间:  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这个目前不是很清楚,下来研究另文说明。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。原著地址