1.1 为什么要进行异常处理
在进行异常处理之前,我们先来看以下这段程序:
public class ExceptionDemo01{ public static void main(String[] args){ int i = 10; int j = 0; System.out.println("==========计算开始=========="); System.out.println("计算结果:" + i / j); System.out.println("==========计算结束=========="); } } |
以上的代码在进行计算完成之后,没有正确退出,而是因为计算产生了异常才退出.那么所谓的异常处理就是指在程序出现问题是依然可以正确的执行完.
1.2 异常处理的格式
在Java中使用try…catch进行异常处理,其完整格式如下:
try{ 可能出现异常的语句 } catch(异常类 异常对象){ 异常处理 }……[1] finally{ 异常的出口; } |
那么现在使用此格式来处理之前的异常;
public class ExceptionDemo02{ public static void main(String[] args){ int i = 10; int j = 0; System.out.println("==========计算开始=========="); try{ double temp = i / j; System.out.println("计算结果:" + temp); // 一旦异常捕获成功,就不在继续向下执行。 }catch(ArithmeticException e){ System.out.println("出现了数学异常:" + e); } System.out.println("==========计算结束=========="); } } |
通过异常处理,可以很好地控制程序的完结.以上的程序在处理的时候还可以使用另外一种格式
public class ExceptionDemo03{ public static void main(String[] args){ int i = 10; int j = 1; System.out.println("==========计算开始=========="); try{ double temp = i / j; System.out.println("计算结果:" + temp); // 一旦异常捕获成功,就不在继续向下执行。 }catch(ArithmeticException e){ System.out.println("出现了数学异常:" + e); }finally{ System.out.println("不管有没有异常,我都执行。"); } System.out.println("==========计算结束=========="); } } |
下面将程序变得更加灵活一些
public class ExceptionDemo04{ public static void main(String[] args){ int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); System.out.println("==========计算开始=========="); try{ double temp = i / j; System.out.println("计算结果:" + temp); // 一旦异常捕获成功,就不在继续向下执行。 }catch(ArithmeticException e){ System.out.println("出现了数学异常:" + e); }finally{ System.out.println("不管有没有异常,我都执行。"); } System.out.println("==========计算结束=========="); } } |
此时发现程序的异常处理并不完善,不输入参数或者输入的参数不正确也都有可能照成程序的异常.
public class ExceptionDemo05{ public static void main(String[] args){ int i = 0; int j = 0; System.out.println("==========计算开始=========="); try{ i = Integer.parseInt(args[0]); j = Integer.parseInt(args[1]); double temp = i / j; System.out.println("计算结果:" + temp); // 一旦异常捕获成功,就不在继续向下执行。 }catch(ArithmeticException e){ System.out.println("出现了数学异常:" + e); }catch(NumberFormatException e){ System.out.println("输入的不是数字:" + e); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("输入的参数个数不对:" + e); }finally{ System.out.println("不管有没有异常,我都执行。"); } System.out.println("==========计算结束=========="); } } |
那么对于本程序而言还是有可能出现其他的异常,总不能就这样一个个的试验每当找到一个异常就去加入catch语句.这样做明显是不合适的.
1.3 异常的处理流程
对于Java来讲,每当程序中出现了异常,实际上都是产生了一个异常类的实例化对象,
·这种处理格式实际上非常类似于方法传参,只要参数类型匹配了,则就可以使用此catch进行处理。
·实际上异常处理的最大父类时:Throwable,但是一般的开发中不会使用此方式进行处理,因为旗下还有两个子类:
·Error:一般表示JVM错误,与程序无关。
·一般指的是程序中的错误,所以一般开发中如果想要进行程序的异常处理,基本上都是使用此类表示。
·一般来讲,在程序捕获异常的时候不要出现Throwable,因为它表示的范围太大了。
public class ExceptionDemo05{ public static void main(String[] args){ int i = 0; int j = 0; System.out.println("==========计算开始=========="); try{ i = Integer.parseInt(args[0]); j = Integer.parseInt(args[1]); double temp = i / j; System.out.println("计算结果:" + temp); // 一旦异常捕获成功,就不在继续向下执行。 }catch(ArithmeticException e){ System.out.println("出现了数学异常:" + e); }catch(NumberFormatException e){ System.out.println("输入的不是数字:" + e); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("输入的参数个数不对:" + e); }catch(Exception e){ System.out.println("其他异常:" + e); }finally{ System.out.println("不管有没有异常,我都执行。"); } System.out.println("==========计算结束=========="); } } |
但是在异常捕获时候需要有一点注意:捕获更细的异常要放在捕获更粗的异常之前。
public class ExceptionDemo07{ public static void main(String[] args){ int i = 0; int j = 0; System.out.println("==========计算开始=========="); try{ i = Integer.parseInt(args[0]); j = Integer.parseInt(args[1]); double temp = i / j; System.out.println("计算结果:" + temp); // 一旦异常捕获成功,就不在继续向下执行。 }catch(Exception e){ // 任何类型的异常都可以接收。 System.out.println("出现异常:" + e); }finally{ System.out.println("不管有没有异常,我都执行。"); } System.out.println("==========计算结束=========="); } } |
当然对于实际开发来说,如果要进行异常处理,则最好分开处理。
1.4 throws关键字
在程序的方法声明处可以使用throws关键字,使用次关键字的:在方法中不处理任何异常而交给被调用处处理.
class Math{ public int div(int i, int j) throws Exception{ return i / j; } } public class ExceptionDemo08{ public static void main(String[] args){ Math m = new Math(); try{ int temp = m.div(10,2); System.out.print(temp); }catch(Exception e){ e.printStackTrace(); // 打印异常也可以使用System.out.print(); } } } |
既然在普通方法上可以使用throws关键字,那么在主方法上呢???
class Math{ public int div(int i, int j) throws Exception{ return i / j; } } public class ExceptionDemo09{ public static void main(String[] args) throws Exception{ Math m = new Math(); int temp = m.div(10,0); System.out.print(temp); } } |
如果在主方法处使用了throws关键字,则所有的异常都交给JVM处理了。
1.5 throw关键字
在程序中可以使用throw关键字认为的抛出一个异常。
则异常处理中,实际上每次产生异常的时候都是产生了一个异常类的实例化对象。那么此时,也可以通过抛出异常对象的方式完成。
public class ExceptionDemo10{ public static void main(String[] args){ try{ throw new Exception("人为抛出异常"); }catch(Exception e){ System.out.print(e); } } } |
1.6 异常的标准格式
现在定义一个div()方法,而且此方法要求有以下的功能。
·进入方法执行计算前要有输出
·此方法执行完之后也要有输出
·如果有异常,则交给被调用处处理。
class Math{ public int div(int i, int j) throws Exception{ System.out.println("==========除法操作之前=========="); int temp = 0; try{ temp = i / j; }catch(Exception e){ throw e; // 抛出异常 }finally{ System.out.println("==========除法操作之后=========="); } return temp; } } public class ExceptionDemo11{ public static void main(String[] args) throws Exception{ Math m = new Math(); try{ int temp = m.div(10,1); System.out.println(temp); }catch(Exception e){ System.out.print(e); } } } |
1.7 RuntimeException
之前学习过将字符串转换为int类型的数据
public static int parseInt(String s)throws NumberFormatException
|
发现此方法中有throws关键字,那么既然有此关键字,就意味着程序中需要使用try…catch进行异常处理操作。
public class ExceptionDemo12{ public static void main(String[] args){ Integer.parseInt("12345"); } } |
但是在使用时根本就没有必要进行异常处理,这又是为什么呢???
NumberFormatException是RuntimeException的子类,那么也就是说只要是RuntimeException的异常对象,虽然使用了throws关键字,但是程序中也可以不使用try…catch进行处理。
1.8 自定义异常
一个类只要继承了Exception就表示一个自定义的异常类。当发现系统中提供的异常类不够用时就可以这样做。
public class ExceptionDemo13{ public static void main(String[] args){ try{ throw new MyException("自定义异常类。"); }catch(Exception e){ e.printStackTrace(); } } } class MyException extends Exception{ public MyException(String msg){ super(msg); } } |
1.9 Assert(断言)关键字(了解)
关键字表示断言,也就是说当程序进行到某条语句之后其结果肯定是固定的值。
public class ExceptionDemo14{ public static void main(String[] args){ int i = 10; assert i == 100; } } |
如果想要验证程序,则需要在执行时加入参数。
java -ea ExceptionDemo14 |
以上输出的信息是JDK默认提供的,其实也可以自己指定输出信息。
public class ExceptionDemo14{ public static void main(String[] args){ int i = 10; assert i == 100 : "值错误!!!"; } } |
但就设实际而言,断言的使用是很少的。