几乎所有的代码里面都会出现异常,为了保证程序在出现异常之后可以正常执行完毕,就需要进行异常处理。
1.异常的继承类结构:
所有的异常都是由Throwable继承而来,他的两个子类是 Error和Exception。
Error类描述了Java运行时内部错误和资源耗尽错误。应用程序不抛出此类异常,这种内部错误一旦出现,除了告知 用户并使程序安全终止之外,再无能无力。(这种情况较少)
在Exception之下又分为两个分支:RuntimeException 和 IOException。
由于程序错误导致的异常属于RuntimeException;而如果程序本身没有问题,但由于像I/O错误这类问题导致的异 常属于IOException。
Java语言规范将派生于Error类或RuntimeException类的所有异常称为非受查异常;所有的其他异常称为受查异常。
2.异常的影响
异常是导致程序中断执行的一种指令流。程序之中如果出现异常并且没有合理处理的话就会导致程序终止执行。
eg:正确程序流:
public class Test {
public static void main(String[] args) {
System.out.println("1.数学计算开始前");
System.out.println("2.进行数学计算:"+ 10 / 2);
System.out.println("3.数学计算结束后"); }
}
此时没有任何异常产生,程序可以正常执行完毕。
eg:产生异常:
public class Test {
public static void main(String[] args) {
System.out.println("1.数学计算开始前");
System.out.println("2.进行数学计算:"+10 / 0);
System.out.println("3.数学计算结束后"); }
}
现在程序之中产生了异常,但是在异常语句产生之前的语句可以正常执行完毕,而异常产生之后程序直接进行了结束。为了保证程序出现异常后还可以继续向下执行,就需要异常处理。
3.异常处理
异常处理的语法格式:
try{
有可能出现异常的语句 ; }
[catch (异常类 对象) { } ... ]
[finally { 异常的出口 }]
对于以上三个关键字,可以出现的组合: try…catch 、 try…finally 、 try…catch…finally
eg:对异常的处理:
public class Test {
public static void main(String[] args) {
System.out.println("1.数学计算开始前");
try {
System.out.println("2.进行数学计算:"+10/0);
}
catch (ArithmeticException e) {
System.out.println("异常已经被处理了");
}
System.out.println("3.数学计算结束后"); }
}
出现了异常之后,由于存在异常处理机制,依然可以正常执行完毕。
为了明确的 取得异常信息,可以直接输出异常类对象,或者调用所有异常类中提供的printStackTrace()方法进行完整异常信息 的输出。
eg:
public class Test {
public static void main(String[] args) {
System.out.println("1.数学计算开始前");
try {
System.out.println("2.进行数学计算:"+10/0);
}
catch (ArithmeticException e) {
e.printStackTrace();
}
System.out.println("3.数学计算结束后"); }
}
在进行异常处理的时候还可以使用 try…catch…finally 进行处理。
eg:
使用 try…catch…finally 进行处理:
public class Test { public static void main(String[] args) {
System.out.println("[1].数学计算开始前");
try {
System.out.println("[2].进行数学计算:"+10/0);
}
catch (ArithmeticException e) {
e.printStackTrace();
}
finally {
System.out.println("[Finally]不管是否产生异常,都执行此语句");
}
System.out.println("[3].数学计算结束后"); }
}
不管此时是否产生异常,终都要执行finally程序代码,所以finally会作为程序统一出口。
以上程序是直接固定好了两个数字进行除法运算,现在通过初始化参数来进行除法运算:
eg:初始化参数进行数学运算
public class Test {
public static void main(String[] args) {
System.out.println("[1].数学计算开始前");
try {
int x = Integer.parseInt(args[0]) ;
int y = Integer.parseInt(args[1]) ;
System.out.println("[2].进行数学计算:"+x/y);
}
catch (ArithmeticException e) {
e.printStackTrace();
}
finally {
System.out.println("[Finally]不管是否产生异常,都执行此语句");
}
System.out.println("[3].数学计算结束后"); }
}
此时会存在如下问题:
1.用户没有输入初始化参数:ArrayIndexOutOfBoundsException
2.用户输入的不是数字: NumberFormatException
3.被除数为0:ArithmeticExceptio
以上代码可以发现,通过catch捕获异常的时候如果没有捕获指定异常,程序依然无法进行处理,现在直白的解决方法就使用多个catch。
eg:多个catch块:
public class Test {
public static void main(String[] args) {
System.out.println("[1].数学计算开始前");
try {
int x = Integer.parseInt(args[0]) ;
int y = Integer.parseInt(args[1]) ;
System.out.println("[2].进行数学计算:"+x/y);
}
catch (ArithmeticException e) {
e.printStackTrace();
}
catch (NumberFormatException e) {
e.printStackTrace();
}
catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
finally {
System.out.println("[Finally]不管是否产生异常,都执行此语句");
}
System.out.println("[3].数学计算结束后");
}
}
这种情况也可以使用if... else
进行判断。