------- android培训、java培训、期待与您交流! ----------
异常其实就是Java对不正常情况进行描述后的对象体现。
对于严重的问题Java通过Error类进行描述(一般不编写针对性代码处理);
对于非严重问题通过Exception类进行描述(可编写针对性代码处理);
接下来将对Exception进行详细说明~
对捕获到的异常对象进行的常见操作:
String getMessage()//获取异常信息
toString()//获取异常名称和异常信息
printStackTrace()//获取异常名称,异常信息,异常出现的位置(JVM默认异常处理机制)
遇到异常时要么进行处理,要么抛出去让调用者处理
处理异常需要用到下面的语句
try{
//需要被检测的代码,也就是可能出错的
}
catch(异常类 变量){
//处理方式
}
finally{
//一定会执行的语句,通常用于关闭资源
}
注意:
try中检测到异常会将异常对象传递给catch,catch捕获到异常进行处理。
finally里通常用来关闭资源。即使在try-catch中执行了return,finally子句仍会执行,finally代码块只有一种情况不会被执行,就是在之前执行了System.exit(0)。
try是一个独立的代码块,在其中定义的变量只在该变量块中有效。如果在try以外继续使用,需要在try外建立引用,在try中对其进行初始化。
trycatchfinally代码块组合特点:
1.try-catch-finally
2.try-catch(多个):当没有资源需要释放时,可以不用定义finally。
3.try-finally:异常无法直接catch处理,但是资源必须关闭。
抛出异常需要用到throws和throw
throws和throw的区别:
1.throws用于标识函数暴露出的异常类,并且可以抛出多个,用逗号分隔。thorws用在函数上,后面跟异常类名。
2.throw用在函数内,后面跟异常对象。
定义功能方法时,需要把出现的问题暴露出来让调用者去处理,那么就通过throws在函数上标识,让调用者try-catch处理或继续抛出。在函数上声明异常提高了安全性,让调用者处理,不处理编译失败~(有种情况不失败,后面说)
在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。若不经行处理,需要在函数上声明让调用者处理。
异常的分类:
1.编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系。这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。
这样的问题都可以针对性的处理。
2.编译时不检测异常(运行时异常):就是Exception中的RuntimeException和其子类。这种问题的发生,无法让功能继续,运算无法运行,更多是因为调用的原因导致的或者
引发了内部状态的改变导致的。那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行调整。
运行时异常
若函数内抛出该异常,函数上可以不用声明;若函数上声明了该异常,调用者可以不用进行处理,编译pass~~
自定义异常
项目中会出现特有的问题,而这些问题并未被Java所描述,封装。so可以进行自定义的异常封装。如果让一个类成为异常类,必须要继承异常体系,因为只有成为异常体
系的子类才有资格具备可抛性,才可以被两个关键字所操作:throws、throw。自定义类继承Exception或者其子类,通过构造函数定义异常信息。P.S.自定义异常出现时,Java
不主动识别,需手动建立对象并抛出。
多异常的处理
声明了几个异常就要处理几个,若异常间有继承关系,处理时,父类catch要放在最下面。
//自定义的数组角标负数异常,运行时异常
class FuShuIndexException extends RuntimeException{
FuShuIndexException(){}
FuShuIndexException(String msg){
super(msg);//传入异常信息,父类有方法处理直接调用
}
}
class Demo{
public static int method(int[] arr, int index) throws NullPointerException,FuShuIndexException{
if(arr == null)
throw new NullPointerException("没有数组实体");//数组为空
if(index < 0){
throw new FuShuIndexException("数组的角标是负数啦");//数组角标负数异常
}
return arr[index];//正常情况
}
}
class ExceptionDemo{
public static void main(String[] args){
int[] arr = new int[5];
try{
int num = Demo.method(arr,-30);//角标为负数
System.out.println("num:" + num);
}
catch(NullPointerException e){
System.out.println(e);
}
//捕获到异常
catch(FuShuIndexException e){
System. out.println("message:" + e.getMessage());
e.printStackTrace(); //jvm 默认的异常处理机制就是调用异常对象的这个方法。
System.out.println("负数角标异常!!!");
}
catch(Exception e){//Exception的catch放在最下面,若放上面就不能做到有针对性处理
System.out.println(e);
}
System.out.println("over" );
}
}
异常在子父类覆盖中的体现
子类在覆盖父类时,若父类方法抛出异常,那么子类的覆盖方法,只能抛出父类异常或者该异常的子类异常。要么不抛!
若父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集,也可不抛。
若父类或接口方法没有抛出异常,那么子类在覆盖方法时,不能抛出异常。
P.S. 也就是说子类不能比父类更有问题!!
异常处理原则
若功能出现不属于该功能的异常并处理不了,可将异常转换后,抛出和该功能相关的异常。或者异常可以处理,但需要将异常产生的和本功能相关的问题提供出去,让调用者处理,也可将捕获到的异常处理后转换新的异常。
try{
throw new AException();
}
catch(AException e){
throw new BException();
}
/*
老师用电脑上课。
上课中电脑出现问题
电脑蓝屏。
电脑冒烟。
当冒烟发生后,出现老师无法继续讲课。
so出现了新的问题-无法上课。
*/
//蓝屏
class LanPingException extends Exception{
LanPingException(String message){
super(message);
}
}
//冒烟
class MaoYanException extends Exception{
MaoYanException(String message){
super(message);
}
}
//没法继续上课
class NoStudyException extends Exception{
NoStudyException(String msg){
super(msg);
}
}
class Computer{
private int state = 3;//表示电脑的状态
public void run()throws LanPingException,MaoYanException{
if(state==2)//状态2时蓝屏
throw new LanPingException("蓝屏了");
if(state==3)//状态3时冒烟
throw new MaoYanException("冒烟了");
System.out.println("电脑运行");
}
//重启电脑
public void reset(){
state = 1;//进入无异常状态
System.out.println("电脑重启");
}
}
class Teacher{
private String name;
private Computer com;
//老师上课要用电脑,电脑自备= =
Teacher(String name){
this.name = name;
com = new Computer();
}
public void teach()throws NoStudyException{
try{
com.run();
}
catch (LanPingException e){
com.reset();//蓝屏处理方式,重启
}
catch (MaoYanException e){
//电脑冒烟时产生无法讲课的问题,此问题是和老师相关的
throw new NoStudyException("课时无法继续"+e.getMessage());
}
System.out.println("讲课");
}
}
class ExceptionTest {
public static void main(String[] args) {
Teacher t = new Teacher("老师A");
try{
t.teach();
}
catch (NoStudyException e){<span style="white-space:pre"> </span>//捕获老师的问题,来处理;调用者处理不了电脑问题
System.out.println(e.toString());
System.out.println("放假");
}
}
}