无论我们走到哪里,不可预测的事件都在等待着我们。地震、人们的非理性行为、陨石……或者更简单的事情——灯泡烧坏、银行卡消磁、汽油表坏了。我们无法阻止不可预测的事件发生,但我们至少可以为它们做好部分准备。也就是说,我们必须准备一定的机制来应对。在编程领域,特别是在Java语言中,阻止程序正常运行的事件称为异常,而防止程序崩溃的机制称为异常处理。因此,当程序中发生意外事件(例如除以零)时,它应该“抛出”异常。异常处理是Java编程的一个重要方面,它可以帮助开发人员管理程序执行期间可能发生的错误和异常。在本文中,我们将重点讨论异常处理的基本概念之一:Java throw关键字以及如何使用它来引发异常。
Java 中的异常是什么?
异常是在程序执行期间发生的破坏程序指令正常流程的事件。当发生异常时,程序执行会停止,并在控制台上显示错误消息。在Java中,有两种类型的异常:受控异常和非受控异常。检查异常在编译时进行检查,编译器确保它们被调用方法捕获或声明。另一方面,未检查的异常在编译时不会被检查,并且它们可以被捕获或不被捕获。下面是一个可能发生错误但编译器会跳过它的代码示例。public class Factorial {
public static long getFactorial(final int number) {
long fact = 1;
for (int i = 1; i <= number; i++) {
fact = fact * i;
}
return fact;
}
public static void main(String[] args) {
System.out.println(getFactorial(-5));
System.out.println(getFactorial(21));
}
}
这是程序的输出:
1 -4249290049419214848
程序正确退出,但产生了错误的结果。在第一种情况下,因为函数参数为负数,并且阶乘不适用于负数。在第二种情况下,结果是错误的,因为数字太大,无法在 long 类型的范围内计算其阶乘。这是另一个例子。让我们编写一个程序,将一个数字除以另一个数字。
public class DivisionExample {
public static void main(String[] args) {
int a = 10;
int b = 0;
int result = divide(a, b);
System.out.println(result);
}
public static int divide(int a, int b) {
return a / b;
}
}
在此示例中,由于变量 b 为零,因此将引发ArithmeticException 。但是,此错误未得到处理,因此程序会以错误状态退出。
Java中如何抛出异常
在Java中,异常也是对象,因此抛出异常就像创建一个新的Exception对象一样。程序中使用 throw 语句抛出异常。通常,这两个操作(对象创建和抛出异常)合并为一个:throw new Exception("error…");
Java 中的throw 关键字用于当发生程序在运行时无法处理的错误或异常情况时,从方法或代码块中抛出异常。程序流程被重定向到最近的 catch 块。该块可以管理异常。
“throw”关键字用法示例
为了说明 Java 中throw关键字的功能,我们举一个例子。让我们编写一个方法来计算数字的阶乘。如果数字为负数,则无法计算,因此必须抛出异常。同样,如果数字太大,阶乘结果将超过 long 类型的最大大小,并且将引发另一个异常。这里我们有该方法的实现:public Class Factorial {
public static long getFactorial(final int number) {
if ((number >= 0) && (number < 21)) {
long fact = 1;
for (int i = 1; i <= number; i++) {
fact = fact * i;
}
return fact;
} else {
//throw new exception here
throw new IllegalArgumentException("THe argument isn't legal");
}
}
public static void main(String[] args) {
System.out.println(getFactorial(-5));
System.out.println(getFactorial(21));
}
}
在此示例中,如果number 的值为负数,则使用throw关键字抛出IllegalArgumentException类的实例。如果运行该程序,控制台上将显示“参数不合法”消息。程序执行将被停止。
不再有错误:捕获异常示例
现在让我们回忆一下第二个例子,除以零,并通过异常处理来执行它。public class DivisionExample {
public static void main(String[] args) {
int a = 10;
int b = 0;
try {
int result = divide(a, b);
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Error: division by zero");
}
}
public static int divide(int a, int b) {
return a / b;
}
}
在此示例中,我们添加了一个try-catch构造来处理被零除异常。简而言之,try-catch-finally是一种 Java 编程语言结构,它允许您处理异常并执行代码,无论是否发生异常。 try-catch-finally由三个块组成:
- try块。这里正在执行潜在危险的代码。那是可以抛出异常的代码。如果try块内发生异常,则中止该块中代码的执行,并将控制权转移到 catch 块。
- 捕获块。这里处理抛出的异常。在catch块中,您可以指定要捕获哪个异常以及捕获时执行什么逻辑。 最后的块。无论是否发生异常,都会执行此操作。例如,finally块用于释放在 try 块中分配的资源(例如关闭文件或套接字)。您可以省略此块。
抛出关键字
throws关键字用在方法签名中。如果是这样,则意味着该方法中抛出了异常。这可以将异常传播到调用堆栈并指示不需要在当前方法中处理异常。在 Java 中,“抛出”也可用于指代程序中定义的自定义异常。 例如,一个方法可以执行两个数字的除法,但如果第二个参数为零, 则抛出IllegalArgumentException :public static double divide(double a, double b) throws IllegalArgumentException {
if (b == 0) {
throw new IllegalArgumentException("Division by zero is not allowed");
}
return a / b;
}
此方法使用 throws 关键字来指示如果第二个参数为 null,则可以抛出IllegalArgumentException 。如果在执行该方法时发生此类异常,则会将其传递给调用方法进行处理。方法调用示例:
public static void main(String[] args) {
double result = 0;
try {
result = divide(10, 0);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("Result: " + result);
}
在此示例中,使用参数 10 和 0 调用divide()方法,由于不可能除以零,因此将抛出IllegalArgumentException 。异常将被try-catch块捕获,并显示错误消息。由于异常终止了divide()方法的执行,因此程序将导致值为零。