自定义异常:
-
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以定义异常。用户自定义异常类,只需继承Exception类即可。
-
在程序中使用自定义类,大体可以分为以下几个步骤
-
创建自定义异常类
-
在方法中通过throw关键字抛出异常对象。
-
如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
-
在出现异常方法的调用者中捕获并处理异常。
-
主要代码分为两个类一个是自己定义的异常类MyException以及一个用来测试的Test类
package com.exception.demo02; //自定义的异常类 public class MyException extends Exception{ //传递数字如果>10抛出异常 private int detail; public MyException(int a) { this.detail=a; } //toString方法Alt+insert用来打印信息 @Override public String toString() { return "MyException{"+ detail + '}'; } }
package com.exception.demo02; public class Test { //可能会存在异常的方法 static void test(int a) throws MyException { System.out.println("传递的参数为"+a); if(a>10){ throw new MyException(a);//由于出现了异常所以要选择是抛出还是捕获,抛出就是现在这种将异常抛出给方法让调用该方法的代码进行捕获,否则就是在此处直接进行try/catch捕获(快捷键Alt+Enter) } System.out.println("OK"); } public static void main(String[] args) { try { test(11);//此时调用了可能有异常的方法要么继续抛要么直接try/catch } catch (MyException e) {//捕获的即为自定义的异常MyException //e.printStackTrace();即为将自定义的异常的消息打印出来 //可以增加一些处理异常的代码块! System.out.println("MyException=>"+e); } } }
对于自定义的异常类MyException类定义时候必须要对Exception异常类进行继承才能说是异常类,此类中私有的定义了一个detail属性用来打印其它方法传递过来的实参,包含一个有参构造器MyException(int a)作用是对于调用该构造器的方法会将其实参a赋给异常类MyException的detail属性以对于建立的Exception异常类的对象的detail属性设置为传递的实参的值a,而对于重写的ToString(原因是父类Eeception也具备ToString方法)方法作用为对于建立的Exception对象如果将要执行相关的println语句时,会自动执行return 语句返回的值代替对象名(此例中为e)来进入println代码块中进行打印。
而对于Test类先是定义了一个test(int a)方法为一个可能存在异常的方法用于进行try的监控区域,对于throws的出现是由于此时通过条件语句判断已经抛出了自定义的异常,但是没有选择用try/catch进行捕捉而是通过使用throws来修饰test(int a)来通过方法来抛出异常,即为:由于出现了异常,故而要在是继续抛出异常还是捕获异常之间选择,抛出就是现在这种将异常抛出给方法让调用该方法的代码进行捕获,否则就是在此处直接进行try/catch捕获(快捷键Alt+Enter)。强调一下快捷键Alt+Enter的作用:对于出现错误提示的代码,使用Alt+Enter能够自动进行修改(这不是异常或者错误(二者都是运行过程出现了错误)而是代码本身出现了语法错误,而导致无法通过编译进而无法运行。)
对于main()函数内为一个try/catch结构体:对于try内部由于为test(11)传递的实参11大于10故而会抛出MyException异常此时如果建立了一个MyException类的对象其detail属性已经被改为11,同时由于发生了MyException的异常故而要执行catch内的代码且由于catch(MyException e)即已经新建了一个MyException异常类的对象e,会打印System.out.println("MyException=>"+e);对于此println内部的e由于ToString重写方法的定义,将会更换为"MyException{"+ detail + '}'其中detail的值已经被赋为11.且对于test()方法首行还有一个执行语句ystem.out.println("传递的参数为"+a);故而执行语句结果为:
传递的参数为11
MyExceptionMyException{11}
对于上一节博客错误的一个总结:对于try/catch语句中的try语句内的代码并非不执行,而是也会被执行,只是因为当执行到发声异常的时候会自动退出此代码块,比如上方中的test(11)时候结果中明明包含:传递的参数为11但却并没有打印出最后一行代码的OK这表示由于11>10抛出了异常使得此块代码已经结束运行,而非上节博客中所写的并未执行!!!
实际应用中的经验总结
-
处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
-
在多重catch块后面,可以加一个catch(Exception)(最大的异常)来处理可能会背遗漏的异常
-
对于不确定的代码,也可以加上try-catch,处理潜在的异常(实际上并不需要在Idea中一般除了大部分逻辑错误以外只要有异常就会提醒,之后按下Alt+Enter就可以提示)
-
尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出(因为快捷键生成的基本上只是将异常信息输出应该去处理才行)如上方代码中Test类中catch抓到异常后可以添加一些代码块来处理这些异常!
-
具体如何处理异常,要根据不同的业务需求和异常类型去决定
-
尽量添加finally语句块去释放占用的资源(如之前的scanner资源!)