Java中所有异常的父类是Throwable类,在Throwable类下有两大子类:
一个是Error类,指系统错误异常,例如:VirtualMachineError 虚拟机错误,ThreadDeath 线程死锁。一般如果是Error类的异常的话,就是程序的硬伤,就好比是工厂里断水断电,机器损坏了。
另一个是Exception类,指编码、环境、用户操作输入等异常,这个是比较常见的异常类,Exception类下面又有两个子类,RuntimeException 非检查异常和检查异常,非检查又称为运行时异常,在RuntimeException异常中有几个常见的子类,例如:
InputMismatchException 输入不匹配异常
ArithmeticException 算术运算异常
NullPointerException 空指针异常
ArrayIndexOutOfBoundsException 数组下标越界异常
ClassCastException 类型转换异常
检查异常中的子类有:
IOException 文件异常
SQLException SQL数据库错误异常
在实际的开发中,处理异常一般使用以下三种方式:
一、使用try-catch语句块捕获和处理异常
使用try-catch 以及 try-catch-finally 来捕获和处理异常时,catch里的异常列表一般是子类在前,父类在后,不然编译时程序会报错。示例如下:
1 import java.util.InputMismatchException; 2 import java.util.Scanner; 3 4 public class 异常处理 { 5 6 public static void main(String[] args) { 7 8 System.out.println("请输入你的年龄"); 9 Scanner input = new Scanner(System.in); 10 try{ 11 System.out.println("请输入第一个数:"); 12 int one = input.nextInt(); 13 System.out.println("请输入第二个数:"); 14 int two = input.nextInt(); 15 System.out.println("两数相除结果为:"+one/two); 16 }catch(InputMismatchException e){ 17 System.out.println("请输入整数"); 18 }catch(ArithmeticException e){ 19 System.out.println("除数不能为零"); 20 }catch(Exception e){ 21 System.out.println("程序执行中出现异常"); 22 }finally{ 23 System.out.println("程序执行结束!"); 24 } 25 26 27 28 } 29 30 }
二、使用throws关键字声明将要抛出何种类型的异常
语法
public void 方法吗(参数)throws 异常列表{ throw new Exception(); }
示例如下:
1 public class ThrowDemo { 2 3 public static void main(String[] args) { 4 5 ThrowDemo td = new ThrowDemo(); 6 try { 7 td.test(10, 0); 8 } catch (Exception e) { 9 System.out.println("异常抛出"); 10 } 11 } 12 13 public void test(int a,int b) throws Exception{ 14 int c = a/b; 15 System.out.println("计算结果为:"+c); 16 17 } 18 19 }
三、自定义异常类
有的时候我们抛出的异常在Throwable类中没有定义,就需要我们自己自定义一个异常的类,比如我们实际开发中需要用到一个“开车别喝酒”的异常,我们就可以定义一个这样的异常类来处理我们项目中需要处理的异常。
自定义异常类的语法:
class 自定义异常类 extends 异常类型{}
自定义异常类需要继承和它类型相近的Throwable类里面的子类,或者是我们直接让自定义异常类继承Exception类,示例如下:
1 /** 2 * 自定义一个异常类 3 * @author lenovo 4 * 5 */ 6 public class MyThrow extends Exception{ 7 8 public MyThrow(){ 9 10 } 11 12 public MyThrow(String mess){ 13 super(mess); 14 } 15 }
使用这个异常类的示例如下:
1 public class ChainTest { 2 3 /** 4 * test1():抛出"喝大了"异常; 5 * test2():调用test1(),捕获"喝大了"异常,并且包装成运行时异常,继续抛出; 6 * main方法中调用test2(),尝试捕获test2()方法抛出的异常 7 */ 8 9 public static void main(String[] args) { 10 ChainTest ct = new ChainTest(); 11 ct.test2(); 12 } 13 14 public void test1() throws MyThrow{ 15 throw new MyThrow("喝酒别开车!"); 16 } 17 18 public void test2(){ 19 try { 20 test1(); 21 } catch (MyThrow e) { 22 RuntimeException newExc = new RuntimeException("司机一滴酒,亲人两行泪~~"); 23 newExc.initCause(e); 24 throw newExc; 25 } 26 } 27 28 }
运行结果:
Exception in thread "main" java.lang.RuntimeException: 司机一滴酒,亲人两行泪~~ at xbw.ChainTest.test2(ChainTest.java:24) at xbw.ChainTest.main(ChainTest.java:13) Caused by: xbw.MyThrow: 喝酒别开车! at xbw.ChainTest.test1(ChainTest.java:17) at xbw.ChainTest.test2(ChainTest.java:22) ... 1 more
Java异常处理实际应用中的经验与总结:
1、处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理;
2、在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常;
3、对于不确定的代码,也可以加上try-catch,处理潜在异常;
4、尽量去处理异常,切忌只是简单的调用printStackTrace()去打印输出;
5、具体如何处理异常,要根据不同的业务需求和异常类型去决定;
6、尽量添加finally语句块去释放占用的资源。