“嗨,阿米戈。今天我们将学习一个非常有趣的课程。我会讲解异常。异常是一种特殊的机制,可以让我们在程序中处理错误。以下是程序中可能发生的一些错误示例:
1.程序可能会在硬盘已满时尝试写入文件。
2.程序可能会尝试在存储空引用的变量上调用方法。
3.该程序可能会尝试将数字除以 0。”
所有这些动作都会导致错误。通常,结果是程序立即终止,因为在这种情况下继续执行代码没有意义。
“为什么?”
“如果汽车冲出道路,从悬崖上掉了下来,继续转动方向盘有意义吗?”
“那么程序应该停止运行吗?”
“是的。这是经常发生的事情。任何错误都会导致程序终止。”
“这是一个非常明智的方法。”
“但是尝试并继续运行程序不是更好吗?”
“是的。假设你在 Word 中键入了大量文本并保存。如果保存操作失败,但是程序使你认为一切正常,该怎么办?然后你继续输入。那太愚蠢了,不是吗?”
“是的。”
“然后,程序员提出了一个有趣的解决方案:每个函数都将返回其工作状态。0 表示它正常运行。任何其他值将意味着出现了错误,返回值就是一个错误代码。”
“但是,这种方法也有缺点。在每个 (!) 函数调用之后,你必须检查返回代码(数字)。首先,这很不方便:错误处理代码很少执行,但一个地方都不能落下。其次,函数通常返回不同的值,你该如何处理?”
"是的。我也想过。”
“然后,异常和错误处理机制完美解决了这个问题。下面是此代码的工作方式:
1.发生错误时,Java 机器会创建一个特殊对象(异常),并在其中保存所有错误信息。不同错误有不同的异常。
2.异常会导致程序立即退出当前函数以及下一个函数,依此类推,直到退出 main 方法为止。然后程序终止。程序员也可以说,Java 机器‘解开调用堆栈’。”
“但是你说程序并不总是终止。”
“是的,因为有一种捕获异常的方法。我们可以在适当的地方编写特殊的代码,以捕获要关注的异常并对其进行处理。这很重要。”
“特殊的 try-catch 结构就为此而生。下面是此代码的工作方式:”
捕获异常(除以 0)并继续工作的程序示例。 |
---|
|
屏幕输出: |
|
“但是‘调用 method1 之后。这将永远不会显示’为何不会显示在屏幕上?”
“问得好。在第 25 行中,我们除以 0,这将导致错误,出现异常。Java 机器创建一个 ArithmeticException 对象及错误信息。对象是异常。”
“method1
方法中出现异常。这将导致方法立即终止。如果不用 try-catch 块,这将导致 main 方法终止。”
“如果 try 块中发生异常,它则会在 catch 块被捕获。该 try 块剩余的代码不会被执行。相反,catch 块将开始执行。”
“我不明白。”
“换句话说,代码的工作方式如下:
1.如果 try 块中发生异常,代码会在发生异常的位置停止执行,此时 catch 块开始执行。
2.如果没有异常发生,那么 try 块执行到最后,而且 catch 块不会执行。”
“嗯哼?"
“想象一下,在每个方法调用之后,我们都会检查该方法是正常返回还是由于异常而突然终止。如果发生异常,那么我们继续执行 catch 块(如果有)来捕获异常。如果没有 catch 块,那么我们终止当前方法,然后调用我们的方法执行相同的检查。”
“我想我现在知道了。”
“太棒了!”
“catch 语句中的‘Exception’是什么意思?”
“所有的异常都是继承 Exception 类的类。我们可以在 catch 块中指定异常类来捕获特定的异常,或者我们指定它们的公有父类 Exception 来捕获所有异常。然后,我们可以从变量 e 中获取所有必要的错误信息(它存储了异常对象的参考信息)。”
“很好!如果我的方法中发生了不同的异常,我能否区别处理?”
“当然,而且应该区别对待。你可以这样做:”
public class ExceptionExample2
{
public static void main(String[] args)
{
System.out.println("程序启动");
try
{
System.out.println("调用 method1 之前");
method1();
System.out.println("调用 method1 之后。这将永远不会显示");
}
catch (NullPointerException e)
{
System.out.println("空引用。已捕获异常");
}
catch (ArithmeticException e)
{
System.out.println("除以零。已捕获异常");
}
catch (Exception e)
{
System.out.println("其他任何错误。已捕获异常");
}
System.out.println("程序仍在运行");
}
public static void method1()
{
int a = 100;
int b = 0;
System.out.println(a / b);
}
}
“该 try 块可以与多个捕获特定类型异常的 catch 块配对。”
“我想我听懂了。我自己写不出来,但如果在代码中碰到,我应该不会害怕。”
GO TO FULL VERSION