在运行时期发生的不正常情况
在java中, 用类的形式对不正常情况进行了描述和封装
描述了不正常的情况的类, 就称为异常类
以前正常流程代码和问题处理代码相结合, 现在将正常流程代码和问题处理代码分离, 提高阅读性
其实异常就是java通过面向对象的思想将问题封装成了对象, 用异常类对其进行描述
不同的问题用不同的类进行具体描述. (比如: 空指针, 下标越界等等)
异常体系问题很多, 意味着描述的类也很多, 将其共性进行向上抽取, 就形成了异常体系
最终问题(不正常的情况) 就分成了两大类
Throwable(可抛出): 无论是Error还是Exception, 都是问题, 问题发生就应该可以抛出, 让调用者知道并处理(Throwable 类是 Java 语言中所有错误或异常的超类,只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出)
- 一般不可处理的. Error(错误)
特点: 是由JVM抛出的严重性的问题
这种问题发生一般不针对性处理. 需要直接修改程序 - 可以处理的. Exception(异常)
// 该体系的特点就在于Throwable及其所有的子类都具有可抛性
可抛性到底指什么? 怎么体现可抛性?
通过两个子类关键字来体现: throw throws , 凡是可以被这两个关键字所 *** 作的类和对象都具备可抛性
//命名特点: 子类的后缀名都是用其父类名作为后缀, 阅读性很强
加端端老师免费领取更多Java资料
异常的分类- 编译时被检测异常: 只要是Exception和其子类都是, 除了特殊子类RuntimeException体系
这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式,这样的问题都可以针对性的处理 - 编译时不检测异常(运行时异常): 就是Exception中的RuntimeException和其子类
这种问题的发生, 无法让功能继续,运算无法进行,更多是因为调用的原因导致的,或者引发了内部状态的改变而导致的,这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行修改
==可能在执行方法期间抛出但未被捕获的 RuntimeException 的任何子类都无需在 throws 子句中进行声明==
声明式处理异常:
public int method(int arr,int index) throws XXXXXException{}
捕捉式处理异常
public int method(int arr,int index){ try{ //需要被检测异常的代码 }catch(异常类 变量){//该变量用于接收发生的异常对象 //处理异常的代码 }finally{ //一定会被执行的代码(无论是否出现异常,catch只要没有执行exit()退出jvm的 *** 作,就一定会执行) //假设catch中return了,finally代码块后面的内容不会被执行,但是finally中的代码一定会执行 } } //多catch情况 try{ //需要被检测异常的代码 }catch(异常类1 变量){//该变量用于接收发生的异常对象 //处理异常的代码 }catch(异常类2 变量){ //处理异常的代码 }catch(Exception 变量){//特别: 多catch情况,异常的父类的catch放在最下面 //处理异常的代码 }
自定义异常
使用自定义异常时,要么继承Exception, 要么继承RuntimeException
throws与throw的区别
- throws使用在函数上, throw使用在函数内
- throws抛出的是异常类, 可以抛出多个, 用逗号隔开, throw抛出的是异常对象
异常处理的原则
异常中的注意事项简单来说,就是子类覆盖父类方法只能抛出父类方法的异常或者父类方法异常的子类,或者父类方法异常的子集
即子类方法不能抛出比被覆盖的父类方法多的异常,也不能抛出父类方法不存在的异常
==注意: 如果父类的方法没有抛出异常, 那么子类覆盖父类方法时绝对不能抛出异常==
如果子类方法确实声明了抛出异常(throws Exception),那么此时对于异常的处理, 只能try, 不能抛出
- 函数内容如果抛出需要检测的异常, 那么函数上必须要声明, 否则必须要在函数内用try catch捕捉,否则编译失败
- 如果调用到了声明异常的函数, 要么try catch, 要么throws, 否则编译失败
- 什么时候catch, 什么时候throws呢?
- 功能内容可以解决, 用catch
- 解决不了, 用throws告诉调用者, 由调用者解决
- 一个功能如果抛出了多个异常, 那么调用时, 必须有多个对应的catch进行针对性的处理
内部有几个需要检测的异常, 就抛几个异常, 抛出几个, 就catch几个class LanPingException extends Exception{ LanPingException(String msg){ super(msg); } } class KaSiException extends Exception{ KaSiException(String msg){ super(msg); } } class NoPlanException extends Exception{ NoPlanException(String msg){ super(msg); } } class Computer{ private int status=1;//改变status的值触发异常 public void run() throws LanPingException,KaSiException{ if(status == 1){ throw new LanPingException("电脑蓝屏了!"); } if(status == 2){ throw new KaSiException("电脑卡死了!"); } System.out.println("电脑运行!"); } public void restart(){ status=0; System.out.println("电脑重启!"); } } class Teacher{ private String name; private Computer comp; Teacher(String name){ this.name=name; comp=new Computer(); } public void prelect() throws NoPlanException{ try{ comp.run(); System.out.println(name+"授课!"); }catch(LanPingException e){//捕捉第一个异常 System.out.println(e.toString());//打印异常 comp.restart();//重启 prelect();//继续授课 }catch(KaSiException e){//捕捉第二个异常 System.out.println(e.toString());//打印异常 lianxi(); //throw e;//抛出异常 throw new NoPlanException("课时进度无法完成! 原因:"+e.getMessage()); // 此代码块部分, 涉及到异常转换的情况,catch捕捉到的异常是KaSiException,但是暴露出去的是NoPlanException //作用是将"我"熟悉的问题进行解决,并将"对方"熟悉的问题进行告知 //这种处理方式也叫做异常的封装,不该暴露的问题内部处理,对外暴露"对方"知道的问题 } } public void lianxi(){ System.out.println("大家做练习!"); } } class ExceptionTest{ public static void main(String[] args){ Teacher t=new Teacher("sunwul"); try{ t.prelect(); }catch(NoPlanException e){ System.out.println(e.toString()+"....."); System.out.println("换人!"); } } }
try catch finally代码块组合特点
- try catch finally --常见组合, 经典案例, 连接数据库(连接数据库,查询等 *** 作(Exception),关闭数据库)
- try catch(多个) --当没有必要资源需要释放时, 可以不用定义finally
- try finally --异常无法直接catch处理, 但是资源需要关闭
- 如果子类在覆盖父类方法时,父类方法抛出了异常,那么子类的方法只能抛出父类方法的异常或者该异常的子类
- 如果父类方法抛出多个异常,那么子类覆盖父类方法时只能抛出父类方法异常的子集
加端端老师免费领取更多Java资料
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)