java异常,捕获与抛出
1、概念:
在java里,所有的异常都有一个共同的祖先Throwable(可抛出)。
Throwable:有两个重要的子类:Exception(异常)和Error(错误)。
Error:是程序无法处理的错误,表示运行应用程序中较严重的问题。
Exception:是程序本身可以处理的异常。
2、处理异常机制
在java中,异常处理机制为:抛出异常,捕捉异常。
抛出异常:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行。
捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。运行时系统从发生异常的方法开始,依次调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止。同时,意味着java程序的终止。
运行时异常会自动抛出。
3、捕获异常:try catch和finally
3.1 try- catch
try{
} catch(Type1 id1) {
} catch (Type2 id2) {
}
public class ExceptionTest {
public static void main(String[] args) {
int ret = 0;
try {
int num1 = 20;
int num2 = 0;
System.out.println(num1 + "/" +num2 + "=" +"你猜我运行吗?");
ret = num1 / num2;
} catch (Exception e) {
System.out.println("程序异常,除数不能为0");
}
System.out.println("ret:" + ret);
}
}
3.2 try catch finally语句
try{
} catch (type1 id1) {
} catch (type2 id2) {
} finally {
}
public class ExceptionTest {
public static void main(String[] args) {
int ret = 0;
try {
int num1 = 20;
int num2 = 0;
System.out.println(num1 + "/" +num2 + "=" +"你猜我运行吗?");
ret = num1 / num2;
} catch (Exception e) {
System.out.println("程序异常,除数不能为0");
} finally {
System.out.println("ret:" + ret);
}
}
}
3.3 小结
try块: 用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch块:用于处理try捕获到的异常。
finally块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句将在方法返回之前被执行。在以下4中特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常
2)在前面的代码中用了System.exit()退出程序
3)程序所在的线程死亡
4)关闭CPU
执行顺序:
1)当try没有捕获到异常时:try语句块语句逐一执行,程序跳过catch语句块,执行finally和其后语句。
2)当try捕获到异常时:catch里没有处理此异常的情况,此异常会抛给JVM处理,finally还会执行,但是后边语句不会执行。
3)当try捕获到异常,catch里有处理此异常的情况,catch里会依次找到匹配的语句,后边的catch不会执行,而try中出现异常之后的语句也不会执行,之后执行finally语句。
4、抛出异常
4.1 throws抛出异常
throws语句用在方法定义时声明该方法要抛出的异常类型,如果抛出的是Exception异常类型,则该方法被声明为抛出所有的异常。多个异常用逗号隔开。
methodName throws Exception1, Exception2,... ExceptionN{
}
4.2 throw抛出异常
throw总是出现在函数体中,用来抛出一个Throwable类型的异常。
程序会在throw语句后立即终止,他后边的语句执行不到,然后在包含它的所有try块从里向外寻找含有与其匹配的catch子句的try块。
5、自定义异常
public class MyExceptionTest extends Exception{
String message;
public MyExceptionTest(String ErrorMessage) {
message = ErrorMessage;
}
@Override
public String getMessage() {
return message;
}
}
throw和throws使用
public class ThrowTest {
public static void main(String[] args) {
int a = 3, b = -1;
try {
int result = division(a, b);
} catch (MyExceptionTest e) {
System.out.println(e.getMessage());
} catch (ArithmeticException e) {
System.out.println("除数不能为0");
} catch (Exception e) {
System.out.println("程序发生了其他异常");
}
}
static int division(int x, int y) throws MyExceptionTest {
if (y < 0) {
throw new MyExceptionTest("除数不能是负数");
}
return x/y;
}
}