异常的概念:
在实际程序开发中,代码可能会产生各种各样没有预料到的异常情况,也可能由超出了程序员可控范围的环境因素产生,如用户的坏数据、试图打开一个根本不存在的文件等。在 Java 中,这种在程序执行时可能出现的一些错误称为异常。异常是一个在程序执行期间发生的事件,它中断了正在执行的程序的正常指令流。异常在 Java 中是作为类的实例的形式出现的。当程序在运行中,某方法出现错误,该方法会创建一个对象,并把它传递给正在运行的系统,该对象称为异常对象。
异常的处理:
当程序发生异常时,程序会中断执行。为了保证程序的有效执行,需要对抛出的异常进行相应的处理。在 Java语言中,处理异常的方式有两种:
1.对异常进行捕捉,并处理异常。该方法不会使程序终止。
2. 将异常向上抛出,交给方法调用者处理。该方法会导致程序终止。
异常的捕捉:
在 Java 语言中,异常的捕捉通过如下语句完成:
try{
//可能会出现异常的代码块
}
catch(Exceptiontype e){
//对Exceptiontype的处理
}
...
finally{
//在try代码块执行后,执行finally代码块
}
注:对于 finally 语句块,无论程序中是否有异常发生,无论 try-catch 语句块如何执行,该语句块都会被执行,但有如下四种特殊情况,finally 语句块不会被执行:
1.在 finally 语句块中发生异常。
2.在前面的代码中使用了 System.exit() 退出程序。
3.程序所在线程消亡。
4.关闭 CPU。
利用异常处理,完成一个简单的整数计算器,使用 try-catch 语句块捕捉InputMismatchException(控制台输入的不是整数)异常,代码如下:
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
int result = 0; //初始化result
Scanner scan = new Scanner(System.in);
try {
System.out.println("please input num1");
int a = scan.nextInt(); //创建int型变量a接收输入的num1
System.out.println("please input an operator");
String op = scan.next(); //创建String型变量op接收输入的operator
System.out.println("please input num2");
int b = scan.nextInt(); //创建int型变量b接收输入的num2
switch (op) {
case "+":
result = a + b; break;
case "-":
result = a - b; break;
case "*":
result = a * b; break;
case "/":
if (b != 0) {
result = a / b; break;
} else { //除数为0报错
System.out.println("The divisor cannot be zero!");
return;
}
default:
System.out.println("illegal operator input!");//输入非法操作符
return;
}
System.out.println("result:" + result);
}catch(InputMismatchException e) { //捕捉异常:输入操作数不是整数
System.out.println("illegal input: " + e.toString());
}
scan.close();
}
}
自定义异常:
通过继承 Exception 类即可自定义异常类,具体步骤如下:
1.继承 Exception 类创建自定义异常类。
2.在放法中通过 throws 关键字抛出异常对象。
3.如果在当前抛出异常的方法中处理异常,可以使用 try-catch 语句块捕获并处理,否则在方法的声明处通过 throws 关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
4.在出现异常的方法的调用者中捕获并处理异常。
代码举例如下:
class CustomException extends Exception{ //创建自定义异常类
String message; //定义String类型变量
public CustomException(String ErrorMessage){//父类方法
message = ErrorMessage;
}
public String getMessage() { //覆盖getMessage()方法
return message;
}
}
public class Test {
static int smaller(int num1, int num2) throws CustomException {
if(num1 <= 0 || num2 <= 0){
throw new CustomException("Non-positive integer used");
}
if(num1 < num2) { return num1; }
else { return num2; }
}
public static void main(String[] args) {
try{
int result = smaller(-1, 0);
System.out.println("result:"+ result);
}catch(CustomException e){
System.out.println(e);
}
}
}
throws 关键字:通常被应用在声明方法时,用来指定方法可能抛出的异常。多个异常可使用逗号分隔。
throw 关键字:通常用于方法体中,并且抛出一个异常对象。程序在执行到 throw 语句时立即终止,它后面的语句都不执行。通过 throw 抛出异常后,如果想在上一级代码中捕获并处理异常,则需要在抛出异常的方法中使用 throws 关键字在方法的声明中指明要抛出的异常;如果要捕捉 throw 抛出的异常,则必须使用 try-catch 语句块。
异常的使用原则:
Java异常强制用户去考虑程序的强健性和安全性。异常处理不应用来控制程序的正常流程,其主要作用是捕获程序在运行时发生的异常并进行相应的处理。编写代码处理某个方法可能出现的异常时,可以遵循以下几条原则:
1.在当前方法声明中使用 try-catch 语句捕获异常。
2.一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。
3.如果父类抛出多个异常,则覆盖方法必须抛出那些异常的一个子集,不能抛出新异常。