目录
一、什么是异常
java编程语言的特点之一是它的健壮性。这意味着错误可以最小化,但并不意味着所有的错误都能在编译的过程中被发现,程序在运行时也会发生错误。运行时发生的错误称为“异常”,也就是说,异常是运行时错误。
发生异常时,不捕获异常,程序将意外终止,并将控制权返回给操作系统。使所有已分配资源的状态保持不变。导致资源泄漏。例如,不能回收为某个程序分配的内存给其他程序使用。要阻止此类情况发送,需要有效的异常处理机制,将先前系统分配的资源回收。
二、try{}catch(){}finally{}介绍
try块:try{}块中放置被监控的可能发送异常的代码
catch块:catch子句应用于try块后,不能单独使用。catch(){}块中处理异常及打印产生异常的原因。其作用域仅限于try块。catch子句可以有多个,但是使用多重catch语句时异常子类应位于其父类之前。
finally块:finally{}块可以选择使用,但必须与try块一起使用。无论try块是否引发异常,finally块中的代码始终都会执行。所以finally块可以执行发生异常时的清理工作,可以包含将资源返回给系统的语句或输出消息的语句。例如数据库连接的关闭。
三、示例说明
1.编写测试类1,OneTest.java
package readinglist.exception;
public class OneTest {
public void jiSuan(int value1,int value2){
try{
int total=value1+value2;
System.out.println("加法运算求和:"+total);
int quotient=value1/value2;
System.out.println("除法商是:"+quotient);
int product=value1*value2;
System.out.println("乘法积是:"+product);
}catch (Exception e){
System.out.println("catch OneTest类 的jiSuan方法异常:"+e);
e.printStackTrace();
}finally {
int sum=value1+value2+value1;
System.out.println("OneTest类 finally语句运行sum:"+sum);
}
System.out.println("OneTest类 异常块之后的语句:"+value1);
}
}
2.编写测试类2,TwoTest.java
package readinglist.exception;
public class TwoTest {
public void testMd(){
try {
OneTest Onetest=new OneTest();
Onetest.jiSuan(1,0);
String str="我是测试 TwoTest 类调用 OneTest类完毕!";
System.out.println(str);
}catch (Exception e){
System.out.println("catch TwoTest类的testMd方法发生异常:"+e);
e.printStackTrace();
}finally {
System.out.println("TwoTest类的testMd方法finally块运行!");
}
System.out.println("TwoTest类的异常块之后的流程走起。。。");
}
public static void main(String[] args) {
TwoTest twoTest=new TwoTest();
twoTest.testMd();
}
}
3.运行 TwoTest.java 类的main方法测试
测试场景1, 如上图,发生了ava.lang.ArithmeticException: / by zero运行时异常。
测试结论:OneTest.java类发生异常后捕获,try块中后续代码不执行,但finally块及后续流程任然执行。程序的后续流程没有在异常处而终止。而TwoTest.java类中的所有流程正常执行,没有进入其catch块(即,异常没有扩撒到调用类的catch块)。
测试场景2,去掉OneTest.java类的异常处理语句:
package readinglist.exception;
public class OneTest {
public void jiSuan(int value1,int value2){
//try{
int total=value1+value2;
System.out.println("加法运算求和:"+total);
int quotient=value1/value2;
System.out.println("除法商是:"+quotient);
int product=value1*value2;
System.out.println("乘法积是:"+product);
// }catch (Exception e){
// System.out.println("catch OneTest类 的jiSuan方法异常:"+e);
// e.printStackTrace();
// }finally {
// int sum=value1+value2+value1;
// System.out.println("OneTest类 finally语句运行sum:"+sum);
// }
System.out.println("OneTest类 异常块之后的语句:"+value1);
}
}
再次运行 TwoTest.java 类的main方法测试如图:
测试结论:OneTest.java类发生异常但是没有捕获处理,所以异常扩散到了调用类TwoTest.java的catch块中被捕获处理,导致OneTest.java类发生异常点后的所有流程都终止执行了,包括调用类TwoTest.java调用点(Onetest.jiSuan(1,0);)到catch捕获之间的所有流程均终止执行了。但TwoTest.java类捕获异常之后的finally块及后续流程正常执行。也就说明:发生异常时,不捕获异常,程序将意外终止。但捕获异常处理后,之后的流程可继续执行。
测试场景3,将OneTest.java和TwoTest.java类的异常处理语句都去掉:
package readinglist.exception;
public class TwoTest {
public void testMd(){
//try {
OneTest Onetest=new OneTest();
Onetest.jiSuan(1,0);
String str="我是测试 TwoTest 类调用 OneTest类完毕!";
System.out.println(str);
// }catch (Exception e){
// System.out.println("catch TwoTest类的testMd方法发生异常:"+e);
// e.printStackTrace();
// }finally {
// System.out.println("TwoTest类的testMd方法finally块运行!");
// }
System.out.println("TwoTest类的异常块之后的流程走起。。。");
}
public static void main(String[] args) {
TwoTest twoTest=new TwoTest();
twoTest.testMd();
}
}
再次运行 TwoTest.java 类的main方法测试如图:
测试结论:OneTest.java类发生异常后未捕获处理,导致OneTest.java类及TwoTest.java类调用点(Onetest.jiSuan(1,0);)之后的所有流程都终止执行了。即,发生异常时,不捕获异常,程序将意外终止。