在异常处理中即使没有main函数 仍然可以正确执行
Exception
1.非检查异常:空指针异常,数组下标越界异常,类型转换异常,算术异常
2.检查异常:文件异常,SQL异常
1.try...catch...finnally简单例子
package pro; import java.util.InputMismatchException; import java.util.Scanner; public class TryCatchTest { /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 //divider除数,result结果 TryCatchTest it = new TryCatchTest(); int result1 = it.test(); System.out.println("程序结束了"+result1); int result2 = it.test2(); System.out.println("执行了finally的异常处理"+result2); } public int test() { int divider = 10; int result = 100; try { while(divider>-1) { divider--; result = result + 100/divider; } return result; }catch(Exception e) { e.printStackTrace(); System.out.println("程序抛出异常了"); return -1; } } public int test2() { int divider = 10; int result = 100; try { while(divider>-1) { divider--; result = result + 100/divider; } return result; }catch(Exception e) { e.printStackTrace(); System.out.println("程序抛出异常了"); return result =999; } finally { System.out.println("这是我的finally。"); System.out.println("这是result的值"+result); } } }
注:finally是一定执行的。打印输出异常信息是 (Exception )e.printStackTrace();
2.向上级抛出异常 throw
3.用户自定义的异常 class 自定义异常类 extends 异常类型{} (注:所有自定义的异常都是继承或者间接继承Exception)
异常链:
package pro; public class ChainTest { /** * test1:抛出喝大了异常 * test2:调用test1,捕获喝大了异常,并且包装成运行时异常,继续抛出 * mian方法中,调用test2,尝试捕获test2捕获的异常 */ public static void main(String[] args) { // TODO 自动生成的方法存根 ChainTest ct = new ChainTest(); try { ct.test2(); }catch(Exception e) { e.printStackTrace(); } } public void test1 () throws DrunkException { throw new DrunkException("开车别喝酒"); } public void test2() { try { test1(); } catch (DrunkException e) { // TODO 自动生成的 catch 块 RuntimeException runExc = new RuntimeException("司机一滴酒,亲人两行泪"); runExc.initCause(e); throw runExc; } } }
新定义的异常中包括产生原始异常的原因.
initCase():这个方法就是对异常来进行包装的,目的就是为了出了问题的时候能够追根究底。因为一个项目,越往底层,可能抛出的异常类型会用很多,如果你在上层想要处理这些异常,你就需要挨个的写很多catch语句块来捕捉异常,这样是很麻烦的。如果我们对底层抛出的异常捕获后,抛出一个新的统一的异常,会避免这个问题。但是直接抛出一个新的异常,会让最原始的异常信息丢失,这样不利于排查问题。举个例子,在底层会出现一个A异常,然后在中间代码层捕获A异常,对上层抛出一个B异常。如果在中间代码层不对A进行包装,在上层代码捕捉到B异常后就不知道为什么会导致B异常的发生,但是包装以后我们就可以用getCause()方法获得原始的A异常。这对追查BUG是很有利的。
简化代码
实际应用中的经验与总结:
1.在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
2. 尽量去处理异常,切忌只是简单的调用printStcackTrace()去打印输出
3.尽量添加finally语句块去释放占用的资源