异常的处理机制
抛出异常
捕获异常
异常处理五个关键字:try , catch , finally , throw , throws
package com; public class Test { public static void main(String[] args) { int a=1; int b=0; //try与catch是一起使用的但是finally却不一定! try{//try监控区域 System.out.println(a/b); //catch 捕获异常(如下方情况异常被捕获不会报错 }catch(ArithmeticException e){//try监控区域出现此类异常(注意必须加上一个变量:例如此时的e)将要执行的代码 System.out.println("程序出现异常,变量b不能为0"); }finally {//无论异常出不出现都会执行的代码块 //finally 处理善后工作 System.out.println("finally"); } //finally 可以不要finally, 其一般执行一些IO,资源(例如Scanner的关闭)的关闭操作 } public void a(){ b(); } public void b(){ a(); } }
此时定义的Test类中故意定义生成一个异常:ArithmeticException即为算术异常(因为此时被除数为0不满足基本规则),对于定义的try,catch,finally的作用:首先try{//结构体},结构体内的代码是要监控是否存在出现异常的区域也就是监控区域。之后为catch(异常名称 异常变量名){//结构体}:表明为如果监控区发声异常名称类型的异常将会执行结构体内的代码。最后对于finally{//结构体}是位于catch之后是用来处理善后工作,本身结构体为无论异常出不出现都会执行的代码块,而且此结构中finally是未必需要的可以不需要,一般finally作用的功能有:执行一些IO,资源(例如Scanner的关闭)等的关闭操作。故结构体为try{}catch(异常参数列表){}finally{}的结构。
当捕获并按照catch的结构体执行后就不会发生异常的报错,而会正常执行代码块来提示发生了异常。catch(异常参数列表)实际上就是:catch(想要捕获的异常类型)
但是对于异常参数列表内定义的异常种类必须要与监控区域内发生的异常一致才不会报错,例如上方将try内的监控区域改为new Test().a();将会报错为栈溢出的错误(更为严重)StackOverflowerError.注意执行完毕后finally仍然执行完毕且是在报错完成之前被打印出来,即为finally内部的代码不会随着异常的发声与否而不发生,而是一定会发生且如果出现异常也会在由于异常而令程序暂停前执行。但是如果异常被捕捉时则会在catch内的代码执行完毕后才会执行。
对于如何判断catch里面想要捕获的异常类型可以是何种类型的判断方法,可以凭借上一节的图片来判断
package com.exception; public class Test2 { public static void main(String[] args) { int a=1; int b=0; //选中要监控的代码,按下快捷键 Ctrl+Alt+T即可选择使用try/catch/finally来建立。 try { System.out.println(a/b); } catch (Exception e) { e.printStackTrace();//打印错误的栈信息 } finally { } } }
这就是catch里面应该是何种异常的判断情况,对于a/b的异常情况已知为ArithmeticException即为算术异常由图可得其在RuntimeException的包含之内且RuntimeException又在Exception之内,而最终Exception又在Throwable之内,故catch括号内除了填写ArithmeticException还可以填写RuntimeException,Exception与Throwable来进行捕捉异常。
try{//try监控区域 if(b==0){//主动抛出异常 使用throw(throws与之完全不同) throw new ArithmeticException();//主动抛出一个该已知异常类型的异常对象(由new来建立) } System.out.println(a/b); //catch 捕获异常(如下方情况异常被捕获不会报错 }catch(Error e){//try监控区域出现此类异常(注意必须加上一个变量:例如此时的e)将要执行的代码 System.out.println("Error"); }catch (Exception e){ System.out.println("Exception"); }catch (Throwable t){ System.out.println("Throwable"); } finally {//无论异常出不出现都会执行的代码块 //finally 处理善后工作 System.out.println("finally"); }
首先对于catch语句可以类似于else if语句一般可以进行叠加,但是对于其内的判断条件有要求,即为上一层的异常必须包含在下一层的异常或者与下一层的异常至少为同级。例如上方Error与Exception为同级而Throwable又包含Exception,如果不满足这个规则Idea将会自动报错。
同时此时对于try语句内运用了throw语句,对于throw语句:一旦遇见并且完成了此代码的执行就一定会抛出缩写的异常,此时的用法为:throw new ArithmeticException();即为直接命名调用不必new出异常类的对象来调用异常的抛出,此时如果b==0,就是抛出ArithmeticException()算术异常的打印以及提示情况。但是注意此时if语句在try结构体内,其内的代码只是用来进行监控异常所用,因此并不可能执行相关的代码,如果此if语句要进行执行就必须放在if语句进行打印如果为:
finally {//无论异常出不出现都会执行的代码块 //finally 处理善后工作 if(b==0){//主动抛出异常 使用throw(throws与之完全不同) throw new ArithmeticException();//主动抛出一个该已知异常类型的异常对象(由new来建立) } System.out.println("finally"); }
则因为执行了if语句异常就会被执行抛出故而此finally结构体就会强制暂停,所以finally的结果不会被打印出来。
package com.exception; public class Test { public static void main(String[] args) { try { new Test().test(1,0); } catch (ArithmeticException e) { e.printStackTrace(); } } //假设这个方法中处理不了这个异常。可以在方法上抛出异常。使用throws实现 public void test(int a,int b) throws ArithmeticException{ if(b==0){//主动抛出异常 使用throw(throws与之完全不同) throw new ArithmeticException();//主动抛出一个该已知异常类型的异常对象(由new来建立)此时下方结果即为报错提示信息 //一般用在方法中使用 } System.out.println(a/b); } }
此代码主要是为了讲解throw以及throws的区别首先对于throw语句用法例子:throw new ArithmeticException();为直接匿名调用来执行出异常抛出的情况,故而只要执行了此代码一定会抛出异常,故而一般与一些if语句一起使用来进行判断。而对于throws一般使用在某个方法定义的末尾即在方法名(参数列表)之后,加上throws 异常类型名,来表示此方法可能发生这类的异常情况,要求调用此方法时必须进行try/catch结构来捕捉异常,否则就会报错,故而对于throws当执行到此的时候未必会发生异常,但对于被throws修饰的方法被调用的时候,必须对于被调用的代码进行监控捕捉的操作,否则一定会报错。而对于throw来new的异常情况只要执行了相关代码就一定会报出一样类型的操作。
而对于固定代码体来建立try/catch/finally的快捷键为:选中要进行监控的代码,按下快捷键 Ctrl+Alt+T即可选择使用try/catch/finally来建立。