异常或异常情况(状态)是程序运行期间发生的错误。Java 中的所有异常都是对象。因此,它们不仅可以在发生异常情况时自动生成,还可以由开发人员自己创建。异常类的层次结构: 异常分为几个类,但它们都有一个共同的祖先——类
Throwable
。它的后代是子类Exception
和Error
。异常 ( Exceptions
) 是程序中原则上可解决和可预测的问题的结果。例如,整数除以零。错误 ( Errors
) 是更严重的问题,Java 规范指出您不应尝试在自己的程序中处理,因为它们是 JVM 级别的问题。例如,如果虚拟机可用的内存已耗尽,就会发生此类异常。该程序仍然无法为 JVM 提供额外的内存。在Java中,所有异常分为三种类型:检查异常(checked
)和非检查异常(unchecked
),其中包括错误(Errors
)和运行时异常(RuntimeExceptions
类后代Exception
)。受控异常是可以并且应该在程序中处理的错误;类的所有后代Exception
(但不是RuntimeException
)都属于这种类型。异常处理可以使用运算符完成try…catch
或转移到程序的外部部分。例如,方法可以传递调用层次结构中较高层中发生的异常,而无需自行处理。未经检查的异常不需要处理,但如果您愿意,您可以处理类异常RuntimeException
。让我们编译并运行以下程序:
class Main {
public static void main(String[] args) {
int a = 4;
System.out.println(a/0);
}
}
启动后,控制台上将显示以下消息:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:4)
该消息显示发生的异常的类别 - ArithmeticException
。这个异常可以这样处理:
class Main {
public static void main(String[] args) {
int a = 4;
try {
System.out.println(a/0);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
}
}
}
现在,将执行一个块,而不是标准错误消息catch
,该块的参数是异常对应的类的对象e(该对象本身可以给任何名称,如果我们想强制抛出,则需要它)例如,再次出现此异常,以便检查其他处理程序)。在这种情况下,该块try
包含可能发生异常的程序片段。一个try
可以对应多个具有不同异常类的catch块。
import java.util.Scanner;
class Main {
public static void main(String[] args) {
int[] m = {-1,0,1};
Scanner sc = new Scanner(System.in);
try {
int a = sc.nextInt();
m[a] = 4/a;
System.out.println(m[a]);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Обращение по недопустимому индексу массива");
}
}
}
如果在启动所提供的程序后,用户从键盘 1 或 2 输入,则该程序将运行而不会产生任何异常。如果用户输入0,则会发生类异常ArithmeticException
,并由第一个块处理catch
。如果用户输入3,就会发生类异常ArrayIndexOutOfBoundsException
(数组越界),由第二个块处理catch
。如果用户输入非整数,例如 3.14,则会发生类异常InputMismatchException
(输入类型不匹配),并且将以标准错误格式抛出,因为我们没有以任何方式处理它。但是,您可以为该类添加一个处理程序Exception
,因为该类是所有其他已检查异常的父类,因此它将捕获其中的任何异常(包括InputMismatchException
)。
import java.util.Scanner;
class Main {
public static void main(String[] args) {
int[] m = {-1,0,1};
int a = 1;
Scanner sc = new Scanner(System.in);
try {
a = sc.nextInt();
m[a-1] = 4/a;
System.out.println(m[a]);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Обращение по недопустимому индексу массива");
} catch (Exception e) {
System.out.println("Произошло ещё Howое-то исключение");
}
}
}
由于异常是建立在类和子类的层次结构上的,因此您应该首先尝试处理更具体的异常,然后才处理更一般的异常。也就是说,如果我们将带有类异常处理的块放在第一位(而不是第三位)Exception
,除了“发生了其他异常”之外,我们永远不会看到任何错误消息(所有异常都会立即被该块捕获,并且不会到达休息)。块的可选添加try…catch
可以是块finally
。放置在其中的命令在任何情况下都会被执行,无论是否发生异常。尽管事实上,当发生未处理的异常时,产生该异常后剩余的程序部分不会被执行。例如,如果在某些冗长的计算过程中发生异常,finally
您可以在块中显示或保存中间结果。链接至来源:异常及其处理
GO TO FULL VERSION