我们知道当我们处理异常的时候,一个是声明,另外一个是捕捉。
捕捉:异常处理的捕捉方式,这是可以对异常进行针对性处理的方式。具体格式是:
1 try 2 { 3 4 //需要被检测的异常 5 6 } 7 catch(异常类 变量)//类似于函数,变量用来接受发生异常的对象的(参数) 8 { 9 10 //处理异常的代码块 11 12 } 13 finally 14 { 15 16 //一定会被执行的代码 17 18 }
那么什么时候用捕捉,什么时候用声明呢?有的是把异常暴露出去,有的是不暴露异常。
我定义合理的功能,功能没有问题,你胡乱传入参数出现的异常,这个时候我就得把异常信息返回给你。如果建立功能的时候,自己能够处理得了,那么就自己处理,如果自己处理不了,那就直接抛出去。一个形象的例子:
我们楼内有灭火器,我们就建立了出现明火的预先处理。我们定义了处理方式,二十多年不出问题也没事。但是一旦出现问题,我们就建立灭火器这个预先处理方式。但是如果此时整个房子着了,这个时候即处理不了了,只能打电话给火警了。
放到try当中的东西是需要检查的不需要检查的就不用管了。catch原则,人家抛的什么问题,我们就针对这个问题处理。生活例子:比如说一个小感冒,自己就能够干好,干嘛非得去医院哇。所以,catch要有针对性的处理。
1 class Demo 2 { 3 4 int[] arr = new int[4]; 5 6 void getValue(int num) 7 { 8 9 try 10 { 11 12 System.out.println(arr[num]);//这里可能出现异常,那么我们就在这个地方来检测 13 14 } 15 catch(IndexOutOfBoundsException e)//这里要有针对性的调用异常类型,进行处理 16 { 17 18 System.out.println("IndexOutOfBoundsException");//对异常进行处理后,程序继续往下进行 19 20 } 21 22 } 23 24 } 25 26 class ExcepDemo2 27 { 28 29 public static void main(String[] args) { 30 31 Demo d = new Demo(); 32 d.getValue(100); //如果这个地方出现异常的话,就会被getValue方法捕捉到,进而进行处理 33 34 } 35 36 }
这里还有一种情况就是,在我们有多个catch的时候,也就是一个函数上声明了多个异常,这个时候在针对性处理的时候,我们就需要有多个catch对其进行处理。这里有个小细节需要注意一下:
1 class Demo 2 { 3 4 void getValue(int[] arr,int num) 5 { 6 7 try 8 { 9 10 System.out.println(arr[num]); 11 12 } 13 catch(IndexOutOfBoundsException e) 14 { 15 16 System.out.println("IndexOutOfBoundsException"); 17 18 } 19 catch(NullPointerException e) 20 { 21 22 System.out.print("NullPointerException"); 23 24 } 25 26 } 27 28 } 29 30 class ExcepDemo2 31 { 32 33 public static void main(String[] args) { 34 35 Demo d = new Demo(); 36 int [] arr = new int[4]; 37 d.getValue(null,100); 38 d.getValue(null,1000); 39 } 40 41 }
如果处理多个catch的时候,出现了多个异常,只能捕捉一个。还有我们如果我们担心发生第三种异常的话,我们会增加一个异常处理,但是如果这个异常类是其他异常类的父类的话,一定要放到最下面。
即:
1 class Demo 2 { 3 4 void getValue(int[] arr,int num) 5 { 6 7 try 8 { 9 10 System.out.println(arr[num]); 11 12 } 13 catch(IndexOutOfBoundsException e) 14 { 15 16 System.out.println("IndexOutOfBoundsException"); 17 18 } 19 catch(NullPointerException e) 20 { 21 22 System.out.print("NullPointerException"); 23 24 } 25 /** 26 *这个地方Exception是IndexOutOfBoundsException 和 NullPointerException父类如果 27 *这个父类放到头部的话,那么出现的异常都被Exception捕捉了,那么下面的也就成了废 28 *话 29 */ 30 catch(Exception e) 31 { 32 33 System.out.println("Unokown Exception!"); 34 35 } 36 37 } 38 39 }
如果把Exception这个放到头部的话,我们会编译失败提示:
异常处理的原则:
异常就是问题。java已经提供给我们常见的描述,我们只需要拿过来用就可以了。描述这个对象,抛出就可以了。如果出现的问题,java没有给出指定的异常类描述,这个时候我们就需要自己来描述。那么try什么时候用呢?你只要使用了声明了异常的类方法,这个时候如果我们能够处理得了,这个时候就该用try。你只要没说,我就不处理,否则盲目的处理问题,只会在问题真正出现的时候,隐藏了要描述的异常。
函数内部,如果抛出需要检测的异常,那么函数上必须要声明,否则必须在函数内用try..catch捕捉,否则编译失败。
如果调用到了声明异常的函数,要么try...catch...要么throws,否则编译失败。
什么时候catch?什么时候throws?
功能内部可以解决用catch,解决不了用throws告诉调用者,由调用者来解决。
一个功能抛出多个异常,那么调用时要用多个catch进行针对性的处理,有几个异常抛几个,抛几个异常,我们就catch几个。