2023年11月29日发(作者:)
解析Java中所有错误和异常的⽗类ble
这篇⽂章主要介绍了Java中所有错误和异常的⽗类ble,⽂章中简单地分析了其源码,说明在代码注释中,需要的朋友可以参考下
在java语⾔中,错误类的基类是,异常类的基类是ion。
1)相同点:和ion都是ble的⼦类,因此和ion⾃⾝及其⼦类都可以作为throw的
使⽤对象,如:throw new MyError();和throw new MyException();其中,MyError类是的⼦类,MyException类是ion的⼦类。
2)不同点:⾃⾝及其⼦类不需要try-catch语句的⽀持,可在任何时候将返回⽅法,如下⾯的⽅法定义:
public String myMethod() {
throw new MyError();
}
其中MyError类是类的⼦类。
ion⾃⾝及其⼦类需要try-catch语句的⽀持,如下的⽅法定义是错误的:
public String myMethod() {
throw new MyException();
}
正确的⽅法定义如下:
public String myMethod() throws MyException {
throw new MyException();
}
其中MyException类是ion的⼦类。
JAVA异常是在java程序运⾏的时候遇到⾮正常的情况⽽创建的对象,它封装了异常信息,java异常的根类为ble,整个类有两个
直接⼦类和是程序本⾝⽆法恢复的严重错误.Exception则表⽰可以被程序捕获并处理的异常错
误.JVM⽤⽅法调⽤栈来跟踪每个线程中⼀系列的⽅法调⽤过程,该栈保存了每个调⽤⽅法的本地信息.对于独⽴的JAVA程序,可以⼀直到该程
序的main⽅法.当⼀个新⽅法被调⽤的时候,JVM把描述该⽅法的栈结构置⼊栈顶,位于栈顶的⽅法为正确执⾏的⽅法.当⼀个JAVA⽅法正常执
⾏完毕,JVM回从调⽤栈中弹处该⽅法的栈结构,然后继续处理前⼀个⽅法.如果java⽅法在执⾏代码的过程中抛出异常,JVM必须找到能捕获异
常的catch块代码.它⾸先查看当前⽅法是否存在这样的catch代码块,如果存在就执⾏该 catch代码块,否则JVM回调⽤栈中弹处该⽅法的栈结
构,继续到前⼀个⽅法中查找合适的catch代码块.最后如果JVM向上追到了main()⽅法,也就是⼀直把异常抛给了main()⽅法,仍然没有找到该异
常处理的代码块,该线程就会异常终⽌,如果该线程是主线程,应⽤程序也随之终⽌,此时 JVM将把异常直接抛给⽤户,在⽤户终端上会看到原始
的异常信息.
ble源代码解析
package ;
import .*;
/**
*
* Throwable是所有Error和Exceptiong的⽗类
* 注意它有四个构造函数:
* Throwable()
* Throwable(String message)
* Throwable(Throwable cause)
* Throwable(String message, Throwable cause)
*
*/
public class Throwable implements Serializable {
private static final long serialVersionUID = -3047285L;
/**
* Native code saves some indication of the stack backtrace in this slot.
* Native code saves some indication of the stack backtrace in this slot.
*/
private transient Object backtrace;
/**
* 描述此异常的信息
*/
private String detailMessage;
/**
* 表⽰当前异常由那个Throwable引起
* 如果为null表⽰此异常不是由其他Throwable引起的
* 如果此对象与⾃⼰相同,表明此异常的起因对象还没有被初始化
*/
private Throwable cause = this;
/**
* 描述异常轨迹的数组
*/
private StackTraceElement[] stackTrace;
/**
* 构造函数,起因对象没有被初始化可以在以后使⽤initCause进⾏初始化
* fillInStackTrace可以⽤来初始化它的异常轨迹的数组
*/
public Throwable() {
fillInStackTrace();
* 获取详细信息
*/
public String getLocalizedMessage() {
return getMessage();
}
/**
* 获取起因对象
*/
public Throwable getCause() {
return (cause==this ? null : cause);
}
/**
* 初始化起因对象,这个⽅法只能在未被初始化的情况下调⽤⼀次
*/
if (ourCause != null)
tackTraceAsCause(s, trace);
}
}
/**
* 打印起因对象的信息
* @param s 打印的流
* @param causedTrace 有此对象引起的异常的异常轨迹
*/
private void printStackTraceAsCause(PrintStream s,
StackTraceElement[] causedTrace)
{
//获得当前的异常轨迹
StackTraceElement[] trace = getOurStackTrace();
//m为当前异常轨迹数组的最后⼀个元素位置,
//n为当前对象引起的异常的异常轨迹数组的最后⼀个元素
int m = -1, n = -1;
//分别从两个数组的后⾯做循环,如果相等则⼀直循环,直到不等或数组到头
while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
m--; n--;
}
StackTraceElement[] trace = getOurStackTrace();
int m = -1, n = -1;
while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
m--; n--;
}
int framesInCommon = - 1 - m;
n("Caused by: " + this);
for (int i=0; i <= m; i++)
n("tat " + trace[i]);
if (framesInCommon != 0)
n("t... " + framesInCommon + " more");
// Recurse if we have a cause
Throwable ourCause = getCause();
if (ourCause != null)
}
/**
* 异常轨迹的深度,0表⽰⽆法获得
*/
private native int getStackTraceDepth();
/**
* 获取指定位标的异常轨迹
*/
private native StackTraceElement getStackTraceElement(int index);
private synchronized void writeObject(OutputStream s)
throws IOException
{
getOurStackTrace();
tWriteObject();
}
}
以下讲述的是平时遇到的,⽐较常见的具体异常情况,跟上⾯有部分重复:
Throwable是所有异常的根,ble
Error是错误,
Exception是异常,ion
Throwable: 有两个重要的⼦类:Exception(异常)和 Error(错误),⼆者都是 Java 异常处理的重要⼦类,各⾃都包含⼤量⼦类。
Error(错误):是程序⽆法处理的错误,表⽰运⾏应⽤程序中较严重问题。⼤多数错误与代码编写者执⾏的操作⽆关,⽽表⽰代码运⾏时
JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运⾏错误(Virtual MachineError),当 JVM 不再有继续执⾏操作所需的内存资源时,
将出现 OutOfMemoryError。这些异常发⽣时,Java虚拟机(JVM)⼀般会选择线程终⽌。
这些错误表⽰故障发⽣于虚拟机⾃⾝、或者发⽣在虚拟机试图执⾏应⽤时,如Java虚拟机运⾏错误(Virtual MachineError)、类定义错误
(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应⽤程序的控制和处理能⼒之 外,⽽且绝⼤多数是程序运⾏时不允许出
现的状况。对于设计合理的应⽤程序来说,即使确实发⽣了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过
Error的⼦类描述。
Exception(异常):是程序本⾝可以处理的异常。
Exception 类有⼀个重要的⼦类 RuntimeException。RuntimeException 类及其⼦类表⽰“JVM 常⽤操作”引发的错误。例如,若试图使⽤空
值对象引⽤、除数为零或数组越界,则分别引发运⾏时异常(NullPointerException、ArithmeticException)和
ArrayIndexOutOfBoundException。
注意:异常和错误的区别:异常能被程序本⾝可以处理,错误是⽆法处理。
⼆、Exception
⼀般分为Checked异常和Runtime异常,所有RuntimeException类及其⼦类的实例被称为Runtime异常,不属于该范畴的异常则被称为
CheckedException。
①Checked异常
只有java语⾔提供了Checked异常,Java认为Checked异常都是可以被处理的异常,所以Java程序必须显⽰处理Checked异常。如果程序没
有处理Checked异常,该程序在编译时就会发⽣错误⽆法编译。这体现了Java的设计哲学:没有完善错误处理的代码根本没有机会被执⾏。
对Checked异常处理⽅法有两种
1 当前⽅法知道如何处理该异常,则⽤atch块来处理该异常。
2 当前⽅法不知道如何处理,则在定义该⽅法是声明抛出该异常。
package ;
import ption;
import ption;
/**
* Checked异常测试⽅法
* @author xy
*
*/
public class CheckedExceptionMethods
{
// 总异常类,既有checkedException⼜有RuntimeException,所以其中的checkedException必须处理
public void method1() throws Exception
{
n("我是抛出异常总类的⽅法");
}
// 捕获并处理这个异常
public void testMethod1_01()
{
try
tackTrace();
}
}
public void testMethod2_02() throws Exception
{
method2();
}
}
我们⽐较熟悉的Checked异常有
otFoundException
MetodException
ption
②RuntimeException
Runtime如除数是0和数组下标越界等,其产⽣频繁,处理⿇烦,若显⽰申明或者捕获将会对程序的可读性和运⾏效率影响很⼤。所以由系
统⾃动检测并将它们交给缺省的异常处理程序。当然如果你有处理要求也可以显⽰捕获它们。
package ;
/**


发布评论