Java 中的链式异常
原文:https://www.studytonight.com/java/chained-exception-in-java.php
在 JDK 1.4 中,链式异常被添加到 Java 中。此功能允许您将一个异常与另一个异常相关联,即一个异常描述另一个异常的原因。例如,考虑一种情况,其中一个方法由于试图除以零而抛出一个算术异常,但是异常的实际原因是一个导致除数为零的输入/输出错误。该方法只会向调用方抛出算术异常。所以打电话的人不会知道异常的真正原因。链式异常用于这种情况。
两个新的构造器和两个新的方法被添加到 Throwable 类中,以支持链式异常。
- 可投掷(可投掷原因)
- 可投掷(弦弦,可投掷原因)
在第一个构造器中,参数原因指定了异常的实际原因。在第二种形式中,它允许我们以字符串形式添加异常描述,并说明异常的实际原因。
getCause() 和 initCause() 是添加到可投掷类的两个方法。
- getCause() 方法返回与当前异常相关联的实际原因。
- initCause() 通过调用异常来设置底层原因(异常)。
是时候举个例子了!
让我们借助一个例子来理解链式异常,这里,程序抛出了一个算术异常,但是导致异常的真正原因是 IOException。我们使用 initCause()方法设置异常的原因。
import java.io.IOException;
public class ChainedException
{
public static void divide(int a, int b)
{
if(b == 0)
{
ArithmeticException ae = new ArithmeticException("top layer");
ae.initCause(new IOException("cause"));
throw ae;
}
else
{
System.out.println(a/b);
}
}
public static void main(String[] args)
{
try
{
divide(5, 0);
}
catch(ArithmeticException ae) {
System.out.println( "caught : " +ae);
System.out.println("actual cause: "+ae.getCause());
}
}
}
捕获:java.lang.ArithmeticException:顶层实际原因:java.io.IOException:原因
例子
让我们再看一个例子来理解链异常,这里抛出了 NumberFormatException,但是异常的实际原因是一个空指针异常。
public class ChainedDemo1
{
public static void main(String[] args)
{
try
{
NumberFormatException a = new NumberFormatException("====> Exception");
a.initCause(new NullPointerException("====> Actual cause of the exception"));
throw a;
}
catch(NumberFormatException a)
{
System.out.println(a);
System.out.println(a.getCause());
}
}
}
异常传播
在 Java 中,异常是从栈顶抛出的,如果异常没有被捕获,它就被放在栈底,这个过程一直持续到到达栈底并被捕获。这就是所谓的异常传播。默认情况下,未检查的异常会在被调用的链中转发。
例子
在本例中,方法 a2 调用的方法 a1 出现异常,方法 a3 调用的方法 a2 出现异常。方法 a3()包含在 try 块中,以提供安全保护。我们知道方法 a1 将引发异常,但在方法 a3()中处理。这称为异常传播。
class ExpDemo1{
void a1()
{
int data = 30 / 0;
}
void a2()
{
a1();
}
void a3()
{
try {
a2();
}
catch (Exception e)
{
System.out.println(e);
}
}
public static void main(String args[])
{
ExpDemo1 obj1 = new ExpDemo1();
obj1.a3();
}
}
Java . lang . arithmeticexception:/by zero
例子
让我们再举一个例子,这里程序从方法 m1()抛出一个 IOException,它在 n1()内部被调用。方法 m1()引发的异常由方法 n1()处理。
import java.io.IOException;
class Demo{
void m1() throws IOException
{
throw new IOException("device error");
}
void n1() throws IOException
{
m1();
}
void p1()
{
try {
n1();
}
catch (Exception e)
{
System.out.println("Exception handled");
}
}
public static void main(String args[])
{
Demo obj = new Demo();
obj.p1();
}
}