本文从三个方面讲Java异常处理:
1.异常处理语句:try{ } catch{ } finally{ } ,throw和throws
2.异常的分类
3.自定义异常
一、try{ } catch{ } finally{ } ,throw和throws
(1) try{ } catch{ } finally{ }
①try代码块:在try代码块中,如果有异常被随后的catch捕获,try块中异常发生以后的代码不能执行
②catch代码块:捕获指定的异常,并提供该异常的处理方法,有时候只是简单的把异常打印到控制台上。catch捕获异常要有顺序,异常应该”由小到大”,否则会出现编译错误
③finally代码块:不管是否出现异常,都会执行finally代码块
package ex;
public class Test {
public static void main(String args[]) {
int []a = new int [5];
try {
System.out.println("In try");
System.out.println(a[6]);
System.out.print("异常之后的下一行"); //这一行没有执行到
}
catch(Exception e) {
System.out.println("In catch");
e.printStackTrace();
}
finally {
System.out.println("In finally");
}
System.out.println("After finally");
}
}
//运行结果
/*In try
In catch
java.lang.ArrayIndexOutOfBoundsException: 6
at ex.Test.main(Test.java:7)
In finally
After finally*/
(2)throw和throws
throw:①抛出异常(系统可以自动抛出的异常不要throw语句)②在当前方法中不想处理时,可以抛出异常交给调用该方法的上一级方法处理
throws:用在声明方法时,表示该方法可能抛出的异常,多个异常用”,”分隔,该方法的调用者要对可能抛出的异常做相应的处理。如果方法中处理了自定义异常,必须用throws声明,否则编译会报错
package ex;
public class Test {
public static void main(String args[]) {
int []a = new int[5];
try {
System.out.println(getArrayElement(a,5));
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("In main,接收到getArrayElement抛来的异常");
}
}
public static int getArrayElement(int []array,int n) throws ArrayIndexOutOfBoundsException{
try{
return array[n];
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("不在本方法中处理,抛给上一级代码");
throw e;
}
}
}
//运行结果
/* 不在本方法中处理,抛给上一级代码
In main,接收到getArrayElement抛来的异常
*/
二、异常的分类
1. Throwable类是Java语言中所有错误或异常的超类,他有两个子类Error和Exception(摘自JDK API)
2. Error是Throwable的子类,用于指示合理的应用程序不应该试图捕获的严重问题。在执行该方法期间,无需在其throws子句中声明可能抛出的但未能捕获的Error的任何子类,因为这些错误可能是再也不会发生的异常条件。(摘自JDK API)
换句话说,Error及其子类异常通常是不需要用代码去处理的,一般是与虚拟机相关的问题。比如:VirtualMachineError(Java虚拟机崩溃)、FactoryConfigurationError(工厂配置错误)
3.Exception类及其子类是Throwable的一种形式,它指出了合理的应用程序想要捕获的条件(摘自JDK API)。
Exception类异常又分为两类:checkException和uncheckedException。checkedException要求客户端代码必须处理异常,否则不能通过编译。如:SQLException。uncheckedException是RuntimeException及其子类异常类,它们被编译器特殊对待,不要求客户端调用时必须处理这种异常,能够通过编译,但是运行时会报错。如:NullPointerException、ArrayIndexOutOfBoundException.
注意:checkedException和语法错误是不一样的,比如:FileNotFoundException是checkedException的一种,只有在打开文件的函数后面加上throws声明或者用try-catch语句处理之后程序才能通过编译,但它并不是语法错误。
三、自定义异常
自定义异常通常定义一个继承自Exception类的子类。一般情况下我们都会直接继承自Exception类,而不是某个运行时的异常类。
自定义异常类的一般格式:
class MyException extends Exception{
public MyException(String msg) {
super(msg);
}
}
//这里拿年龄输入错误为例:
package ex;
import java.util.Scanner;
public class Test {
public static void main(String args[]) {
try
{
int age = Test.getUserAge();
}
catch(AgeException e) {
e.printStackTrace();
}
}
public static int getUserAge() throws AgeException{
Scanner sc = new Scanner(System.in);
System.out.print("请输入您的年龄:");
int age = sc.nextInt();
sc.close();
if(age <= 0) {
throw new AgeException("年龄必须为正数!");
}
else if(age >= 120) {
throw new AgeException("这也太老了吧");
}
return age;
}
}
class AgeException extends Exception{
public AgeException(String msg){
super(msg);
}
}
//运行结果
/* 请输入您的年龄:-1
ex.AgeException: 年龄必须为正数!
at ex.Test.getUserAge(Test.java:19)
at ex.Test.main(Test.java:7)
*/
//如有错误,欢迎指正