Java异常机制是Java提供的一种识别及响应错误的一致性机制。
Java异常机制可以使程序中的异常处理代码和正常业务代码相分离,保证程序代码清晰,并提高了程序的健壮性。Java异常机制可以让我们在程序发生问题时知道发生了什么类型甚至什么问题,还可以通过异常堆栈跟踪知道在哪里发生了问题,根据异常信息知道为什么会发生问题。综合这些信息便可以有效地及时地发现问题,然后很有针对性的处理问题。
Java异常机制用到的几个关键字:
Try:用于监听可能发生异常的代码。将可能发生异常的代码放在try语句块之内,当try语句块内发生异常,异常就被抛出。
Catch:用于捕获异常。catch用来捕获try语句块内发生的异常并其语句块内给出针对该异常的处理代码。这样异常处理代码和正常业务代码相分离。
Finally:finally语句块内的代码绝大多数情况下总会被执行。它主要用于释放程序中打开的资源(如数据库连接、网络连接和输入输出流)。只有finally语句块执行完成以后,才会回来执行try或catch语句块中的return或者throw语句。但是如果finally语句块之前出现调用exit()将直接停止JVM,finally语句块不会被执行。
Throw:用于抛出异常。
Throws:声明方法可能抛出的异常。
强调一下:throws用在函数上,后面跟的是异常类,可以跟多个,用逗号隔开。并且调用该函数的地方要么再用throws抛出异常,要么捕获异常并处理,否则编译不通过。
throw后跟异常对象,当函数内部有throw抛出的异常对象,要么立即捕获有异常的代码并处理异常,要么用throws在函数上声明让该函数的调用者处理否则编译不通过。
Java异常分类:
【1】运行时异常:RuntimeException及其子类都被称为运行时异常。Java编译器不会检查它。也就是说,当源程序中可能出现这类异常时,倘若既"没有通过throws声明抛出它",也"没有用try-catch语句捕获它",还是会编译通过。虽然Java编译器不会检查运行时异常,但是我们也可以通过throws进行声明抛出,也可以通过try-catch对它进行捕获处理。 如果产生运行时异常,则需要通过修改代码来进行避免。
【2】被检查的异常:Exception类本身,以及Exception的子类中除了"运行时异常"之外的其它子类都属于被检查异常。 Java编译器会检查它。此类异常,要么通过throws进行声明抛出,要么通过try-catch进行捕获处理,否则不能通过编译。
【3】 错误: Error类及其子类。和运行时异常一样,编译器也不会对错误进行检查。按照Java惯例,我们是不应该是实现任何新的Error子类的!
try和catch用法的小例子:
public class Demo1 {
public static void main(String[] args) {
try {
int i = 10/0;
System.out.println("i="+i);
} catch (ArithmeticException e) {
System.out.println("Caught Exception");
System.out.println("e.getMessage(): " + e.getMessage());
System.out.println("e.toString(): " + e.toString());
System.out.println("e.printStackTrace():");
e.printStackTrace();
}
}
}
运行的结果:
Caught Exception
e.getMessage(): / by zero
e.toString(): java.lang.ArithmeticException: / by zero
e.printStackTrace():
java.lang.ArithmeticException: / by zero
at Demo1.main(Demo1.java:6)
结果说明:在try语句块中有除数为0的操作,该操作会抛出java.lang.ArithmeticException异常。通过catch,对该异常进行捕获。
观察结果我们发现,并没有执行System.out.println("i="+i)。这说明try语句块发生异常之后,try语句块中的剩余内容就不会再被执行了。
finally用法的例子:
public class Demo2 {运行结果:
public static void main(String[] args) {
try {
int i = 10/0;
System.out.println("i="+i);
} catch (ArithmeticException e) {
System.out.println("Caught Exception");
System.out.println("e.getMessage(): " + e.getMessage());
System.out.println("e.toString(): " + e.toString());
System.out.println("e.printStackTrace():");
e.printStackTrace();
} finally {
System.out.println("run finally");
}
}
}
Caught Exception
e.getMessage(): / by zero
e.toString(): java.lang.ArithmeticException: / by zero
e.printStackTrace():
java.lang.ArithmeticException: / by zero
at Demo2.main(Demo2.java:6)
run finally
throw和throws用法的例子:
class MyException extends Exception {
public MyException() {}
public MyException(String msg) {
super(msg);
}
}
public class Demo3 {
public static void main(String[] args) {
try {
test();
} catch (MyException e) {
System.out.println("Catch My Exception");
e.printStackTrace();
}
}
public static void test() throws MyException{
try {
int i = 10/0;
System.out.println("i="+i);
} catch (ArithmeticException e) {
throw new MyException("This is MyException");
}
}
}
运行结果:
Catch My Exception
MyException: This is MyException
at Demo3.test(Demo3.java:24)
at Demo3.main(Demo3.java:13)
结果说明:
MyException是继承于Exception的子类。test()的try语句块中产生ArithmeticException异常(除数为0),并在catch中捕获该异常;接着抛出MyException异常。main()方法对test()中抛出的MyException进行捕获处理。