------- android培训、java培训、期待与您交流! ----------
java基础之异常处理
1、异常概述
所谓异常,就是在程序运行过程中出现的不正常情况,也就是程序中出现的问题。java按照面向对象的思想对这些问题进行了描述,例如,问题产生的原因,问题的名称,对问题描述的信息等,并把问题封装成了对象,便于对问题进行操作和处理。
2、异常体系
问题有很多种类型,比如角标越界,空指针,内存溢出等,这些问题都有共性的内容,比如问题出现的原因,位置,对问题的描述信息等,把这些共性内容不断向上抽取并封装成类或接口,就形成了异常体系。这个体系中的所有类和对象都有一个独有的特点:可抛性。
问题可以分为两类:Error、Exception
Error:错误。一般不编写针对性代码进行处理。
Exception:异常。需要进行针对性处理。
3、异常处理
当定义一个功能时,如果功能内部可能会出现问题,那么,应该在功能上把问题标示出来,让功能调用者在调用该功能时对问题进行处理。可以通过throws关键字完成对问题的声明。这样功能调用者在使用功能时必须进行异常处理,否则编译失败。
异常处理的方式有两种:捕捉或抛出。
对于捕捉:就是编写针对性的代码对异常进行处理。
格式:
try{
需要被检测的代码
}
catch(异常类 异常对象的引用){
异常处理代码
}
finally{
一定会执行的代码
}
4、异常处理的原则
(1)、如果功能抛出了多个异常,对异常进行try处理时,功能抛出了几个异常就必须有几个相应的catch处理代码块,抛出几个处理几个。
(2)、如果一个try对应多个catch,当catch中有异常的父类时,父类必须放在最下面。
public class ExceptionDemo { public static void main(String[] args) { DivDemo d = new DivDemo(); int x; try { //调用的函数声明了异常,可以声明,也可以捕捉,这里进行了捕捉 x = d.div(4, -1); System.out.println("结果是:"+x); } catch (FushuException e) { System.out.println(e.toString()); //打印异常信息 System.out.println("负数是:"+e.getNum()); } System.out.println("over"); } } //自定义异常,创建异常类继承Exception类 class FushuException extends Exception{ private int num;//定义子类特有的属性 FushuException(String msg,int num){ super(msg);//使用父类对象的初始化方式 this.num = num; } public int getNum(){ return num; } } class DivDemo{ //函数中抛出了异常对象,函数上也要声明 int div(int a,int b) throws FushuException{ if(b<0) //函数中抛出了异常对象,调用者必须处理,或者声明或者try throw new FushuException("除数出现负数",b); return a/b; } }
throw和throws的区别:
throw:抛出的是异常对象。用在函数内部。
throws:抛出的是异常类,可以是多个异常类,用逗号隔开。使用在函数上
5、一般情况下,如果功能内部没有对可能出现的异常进行处理而是抛出了异常对象,那么必须在功能上声明,否则编译失败,但也有特殊情况,比如运行时异常。
运行时异常RuntimeException,是Exception的子类,是编译时不被检查的异常。
编译时异常和运行时异常的区别:
编译时异常:编译时被检查,如果函数内抛出了异常,那么必须在函数上声明,让调用者对异常做针对性处理。
运行时异常:运行时发生的异常,编译时不做检查,运行时异常产生,希望程序停止,让调用者对代码进行修正
定义异常处理时,如果功能内部可以对异常进行处理,则使用try进行捕捉处理,如果内部处理不了,就在函数上用throws抛出,让调用者去处理。
6、自定义异常
在实际开发中,可能会出现java没有定义过的异常,这时我们可以按照java面向对象的思想对这些问题进行描述并封装成对象,这就是自定义异常。
自定义异常的步骤:
(1)、定义类继承Exception或RuntimeException,让该类具备可抛性
(2)、通过throw或throws进行操作
* * 练习:毕老师用电脑上课 * 问题:电脑蓝屏 * 电脑冒烟 * 分析: */ public class ExceptionTest01 {// 主类 public static void main(String[] args) { Teacher t = new Teacher("毕老师"); try { t.prelect();// 讲课功能中抛出了课时计划异常 } catch (NoplanException e) { System.out.println("换老师");// 处理课时计划异常 } } } class LanpingException extends Exception {// 自定义电脑蓝屏异常 LanpingException(String msg) { super(msg); } } class MaoyanException extends Exception {// 自定义电脑冒烟异常 MaoyanException(String msg) { super(msg); } } class NoplanException extends Exception {// 自定义课时无法继续异常 NoplanException(String msg) { super(msg); } } class Computer {// 描述电脑类 int state = 1;// 定义状态变量,记录电脑状态 public void run() throws LanpingException, MaoyanException {// 电脑运行时可能会发生的异常 if (state == 2) throw new LanpingException("蓝屏了"); if (state == 3) throw new MaoyanException("冒烟了"); System.out.println("电脑运行"); } public void reset() { System.out.println("重启电脑"); state = 1; } } class Teacher { private String name; private Computer cmpt; Teacher(String name) { this.name = name; cmpt = new Computer(); } public void prelect() throws NoplanException {// 老师讲课需要使用电脑运行,运行声明了异常,需要处理 try { cmpt.run(); } catch (LanpingException e) { System.out.println(e.toString()); cmpt.reset(); } catch (MaoyanException e) {// 冒烟了无法直接处理,抛了也没有,所以抛出其他异常:影响讲课 System.out.println(e.toString()); throw new NoplanException("课时完不成");// throw 出对象时,该函数就结束了 } System.out.println("讲课"); } }
注意:当出现的异常是调用者处理不了的时候,就需要将此异常转化为一个调用者可以处理的异常抛出。这就是异常转换思想。
异常出现后,子父类覆盖时要注意:
(1)、如果父类或接口中的方法抛出了异常,那么子类在对方法覆盖时,只能抛出父类的异常及其异常的子类,或者不抛,不能抛出其他异常
(2)、如果父类或接口中的方法抛出了多个异常,那么子类只能抛出父类或接口方法异常的子集,或者不抛。
(3)、如果父类或接口中的方法没有抛出异常,那么子类也不能抛出异常,如果子类覆盖的方法中出现了异常,只能内部处理,如果处理不了,就通过throw抛出运行时异常对象,这样子类方法上是不需要用throws声明异常的。
/* * 练习:求圆形和正方形的面积,对可能出现的问题进行异常处理 * 分析:图形都有面积,定义图形接口,和求面积的抽象方法。定义圆形和正方形类,实现图形接口。 * 定义异常类实现Exception类,对出现的问题进行描述 */ public class ExceptionTest02 { public static void main(String[] args) { Rec rec = new Rec(-2); rec.getArea(); } } interface Shap { void getArea(); } class Rec implements Shap { public static final double PI = 3.14; private int redius; Rec(int redius) { if (redius <= 0) throw new NoValueException("数值非法"); this.redius = redius; } public void getArea() { System.out.println(redius * redius * PI); } } class NoValueException extends RuntimeException { private String msg; NoValueException(String msg) { super(msg); } }