Java中的异常
异常Exception分为两类,一类是编译时异常(除RuntimeException外的Exception以及它的直接子类),一类是运行时异常(RuntimeException以及它的子类)。
编译时异常是一种发生概率较高的异常,在编写程序时必须预先对它进行处理,否则编译器不能通过。它是发生在程序运行阶段的异常,又被称为受检异常或受控异常。
运行时异常是一种发生概率较低的异常,在编写程序阶段可不对它进行处理。它是发生在程序运行阶段的异常,又被称为不受检异常或不受控异常。
1. 在方法的声明位置上,使用throws关键字,将异常向上一级抛出。
若异常发生后,异常一直上抛,直到抛给了JVM,则程序终止执行。如下所示:
package com.pyi.blog;
public class ExceptionTest1 {
public static void main(String[] args) throws Exception {
int a=10;
int b=0;
System.out.println(a+"/"+b+"="+a/b);
System.out.println("111");
}
}
运行结果如下:
在上面这段程序中,在main方法中发生了算术异常,而main( )方法中并未对其进行捕捉而是向上抛出,抛给了JVM,JMV无法对其进行处理,因此程序终止执行,后面的代码无法运行。在这段程序中,也可以不手动定义main( )方法中对异常的处理,因为ArithmeticException的父类为RuntimeException,它们属于运行时异常,可以不再编写程序阶段对该异常进行异常处理。
package com.pyi.blog;
public class ExceptionTest2 {
public static void main(String[] args) {
ExceptionTest2 e=new ExceptionTest2();
e.myException();
}
public void myException() throws MyException{
}
}
class MyException extends Exception{
}
在上面这段程序中自定义了一个异常类MyException,它的直接父类为Exception,因此它为编译时异常。在myException( )方法声明时抛出了该异常,表示在执行此方法时很可能发生这种异常。因此在调用这个方法处,要对这种异常进行处理,否则编译器报错。如下图所示:
在调用myException( )方法处,对MyException异常进行抛出。
此时编译器通过。
2. 使用try-catch关键字对异常进行捕捉。
try{}尝试运行的代码,catch(){}指捕捉异常。
package com.pyi.blog;
public class ExceptionTest2 {
public static void main(String[] args) {
ExceptionTest2 e=new ExceptionTest2();
try{
e.myException();
System.out.println("111");
}catch(MyException ex){
System.out.println("222");
}
System.out.println("333");
}
public void myException() throws MyException{
throw new MyException();
}
}
class MyException extends Exception{
public MyException() {
}
public MyException(String message) {
super(message);
}
}
在上段程序中,在main( )方法中对MyException类的异常做了捕获处理,因此try-catch后面的代码可以执行,而try的花括号内,因为第一行发生了异常,因此后面对“111”的打印不能完成。运行结果如下:
方法中出现异常,如果采取上报的方式,则此方法结束。
try后面也可以使用多个catch捕捉不同的异常:
package com.pyi.blog;
public class ExceptionTest2 {
public static void main(String[] args) {
ExceptionTest2 e=new ExceptionTest2();
try{
e.myException2();
e.myException();
System.out.println("111");
}catch(MyException ex){
System.out.println("222");
System.out.println(ex);
}catch(MyException2 ex2){
System.out.println("aaa");
}
System.out.println(333);
}
public void myException() throws MyException{
throw new MyException();
}
public void myException2() throws MyException2{
throw new MyException2();
}
}
class MyException extends Exception{
public MyException() {
}
public MyException(String message) {
super(message);
}
}
class MyException2 extends Exception{
}
运行结果如下:
catch后面的参数可以是具体的异常类型,也可以是一个父类,使用多态的形式。可以使用多个catch,在使用多个catch时要注意父类的异常放在子类异常的后面。
JDK8或以后,多个异常参数可以用“或”(|)连接。如:catch(MyExCeption|MyException2|MyException3)
。
1. getMessage( )
getMesage( )方法的作用是获取此可抛出对象的详细消息字符串 。如下所示:
package com.pyi.blog;
public class ExceptionMessageTest {
public static void main(String[] args) {
Exception e=new ArithmeticException("算术异常发生!");
String s=e.getMessage();
System.out.println(s);
}
}
运行结果如下:
2.printStackTrace( )
printStackTrace( )方法的作用是将此可抛出对象及其回溯打印到指定的打印程序。 。如下所示:
package com.pyi.blog;
public class ExceptionMessageTest {
public static void main(String[] args) {
Exception e=new ArithmeticException("算术异常发生!");
String s=e.getMessage();
System.out.println(s);
e.printStackTrace();
System.out.println("111");
}
}
运行结果如下:
finally必须与try-catch一起使用,它里面的代码一定会执行。
package com.pyi.blog;
public class FinallyTest {
public static void main(String[] args) {
try{
exception();
}catch(MyException0 e){
System.out.println("111");
}finally{
System.out.println("222");
}
}
public static void exception() throws MyException0{
throw new MyException0();
}
}
class MyException0 extends Exception{
}
运行结果如下:
可以不写catch,try与fianlly连用。
package com.pyi.blog;
public class FinallyTest1 {
public static void main(String[] args) {
try{
System.out.println("111");
return ;
}finally {
System.out.println("222");
}
}
}
运行结果如下:
在上面这段程序中,先执行try中的System.out.println(“111”),然后执行finally中的代码,最后执行try中的return。因此finally花括号中的代码一定会执行。
try或fianlly不能单独使用。
可以自定义一个异常类,让它继承Exception或者继承RuntimeException,然后为它添加有参和无参构造方法。如下所示:
package com.pyi.blog;
public class MyExceptionTest extends Exception{
public MyExceptionTest() {
}
public MyExceptionTest(String message) {
super(message);
}
}
package com.pyi.blog;
public class MyExceptionTest2 extends RuntimeException{
public MyExceptionTest2() {
}
public MyExceptionTest2(String message) {
super(message);
}
}
package com.pyi.blog;
public class ZiDingYiExceptionTest {
public static void main(String[] args) {
MyExceptionTest e=new MyExceptionTest("编译时异常");
String s=e.getMessage();
System.out.println(s);
e.printStackTrace();
MyExceptionTest2 e2=new MyExceptionTest2("运行时异常");
String s2=e2.getMessage();
System.out.println(s2);
e2.printStackTrace();
}
}
运行结果如下: