黑马程序员_异常体系

时间:2022-10-06 00:43:39

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

什么是异常:

异常:就是不正常。程序在运行时出现的不正常情况。其实就是程序中出现的问题。这个问题按照面向对象思想进行描述,并封装成了对象。因为问题的产生有产生的原因、有问题的名称、有问题的描述等多个属性信息存在。当出现多属性信息最方便的方式就是将这些信息进行封装。异常就是java按照面向对象的思想将问题进行对象封装。这样就方便于操作问题以及处理问题。

 

出现的问题有很多种,比如角标越界,空指针等都是。就对这些问题进行分类。而且这些问题都有共性内容比如:每一个问题都有名称,同时还有问题描述的信息,问题出现的位置,所以可以不断的向上抽取。形成了异常体系。 

 

Throwable

Throwable表示Java中可被抛出的对象,它是所有错误和异常的父类

Throwable有两个子类:ErrorException

Error表示错误

Exception表示异常

RuntimeException表示运行时异常,是Exception的子类

黑马程序员_异常体系

 

异常的分类

Error(错误)

Java虚拟机生成并抛出,包括动态链接失败、虚拟机错误等,程序对其不进行处理

Exception(异常

所有异常类的父类,子类定义了各种各样可能出现的异常事件,一般需要用户显式地声明向外抛出或捕获。

Runtime Exception(运行时异常)

一类特殊的异常,如被0除、数组角标越界等。产生比较频繁,处理麻烦,如果每次都处理,会对程序可读性和运行效率影响比较大,因此由系统检测并将它们交给缺省的异常处理程序,用户不必对其进行处理。这类异常不处理,编译时不会报错,只是在运行时出现错误时才报告异常,所以我们称之为运行时异常,所有RuntimeException的子类都是运行时异常。我们也可以对运行时异常进行处理。

编译时异常

Exception中除了RuntimeException的子类,其他异常都是必须要处理的,如果不处理,编译时会报错,这些异常我们称之为编译时异常。

 

异常体系中的所有类和对象都具备一个独有的特点;就是可抛性

可抛性的体现:就是这个体系中的类和对象都可以被throws和throw两个关键字所操作。

在开发时,如果定义功能时,发现该功能会出现一些问题,应该将问题在定义功能时标示出来,这样调用者就可以在使用这个功能的时候,预先给出处理方式。

 

如何标示呢?通过throws关键字完成,格式:throws 异常类名,异常类名...

这样标示后,调用者,在使用该功能时,就必须要处理,否则编译失败。

 

处理方式有两种:1、捕捉;2、抛出。

对于捕捉:java有针对性的语句块进行处理。

try {

需要被检测的代码;

}

catch(异常类 变量名){

异常处理代码;

}

fianlly{

一定会执行的代码;

}

--------------------------------------------------------

catch (Exception e) { //e用于接收try检测到的异常对象。

System.out.println("message:"+e.getMessage());//获取的是异常的信息。

System.out.println("toString:"+e.toString());//获取的是异常的名字+异常的信息。

e.printStackTrace();//打印异常在堆栈中信息;异常名称+异常信息+异常的位置。

}

---------------------------------------------------------

异常处理原则:功能抛出几个异常,功能调用如果进行try处理,需要与之对应的catch处理代码块,这样的处理有针对性,抛几个就处理几个。

 

特殊情况:try对应多个catch时,如果有父类的catch语句块,一定要放在下面。

 

throw 和throws关键字的区别:

throw用于抛出异常对象,后面跟的是异常对象;throw用在函数内。

throws用于抛出异常类,后面跟的异常类名,可以跟多个,用逗号隔开。throws用在函数上。

 

通常情况:函数内容如果有throw,抛出异常对象,并没有进行处理,那么函数上一定要声明,否则编译失败。但是也有特殊情况。

 

异常分两种:

1:编译时被检查的异常,只要是Exception及其子类都是编译时被检测的异常。

2:运行时异常,其中Exception有一个特殊的子类RuntimeException,以及RuntimeException的子类是运行异常,也就说这个异常是编译时不被检查的异常。

 

编译时被检查的异常和运行时异常的区别:

编译被检查的异常在函数内被抛出,函数必须要声明,否编译失败。

声明的原因:是需要调用者对该异常进行处理。

运行时异常如果在函数内被抛出,在函数上不需要声明。

不声明的原因:不需要调用者处理,运行时异常发生,已经无法再让程序继续运行,所以,不让调用处理的,直接让程序停止,由调用者对代码进行修正。

 

定义异常处理时,什么时候定义try,什么时候定义throws呢?

功能内部如果出现异常,如果内部可以处理,就用try;

如果功能内部处理不了,就必须声明出来,让调用者处理。

 

自定义异常:当开发时,项目中出现了java中没有定义过的问题时,这时就需要我们按照java异常建立思想,将项目的中的特有问题也进行对象的封装。这个异常,称为自定义异常。

 

对于除法运算,0作为除数是不可以的。java中对这种问题用ArithmeticException类进行描述。对于这个功能,在我们项目中,除数除了不可以为0外,还不可以为负数。可是负数的部分java并没有针对描述。所以我们就需要自定义这个异常。

 

自定义异常的步骤:

1:定义一个子类继承Exception或RuntimeException,让该类具备可抛性。

2:通过throw 或者throws进行操作。

 

异常的转换思想:当出现的异常是调用者处理不了的,就需要将此异常转换为一个调用者可以处理的异常抛出。

 

try  catch  finally的几种结合方式:

1,

try 

catch

finally

 

这种情况,如果出现异常,并不处理,但是资源一定关闭,所以try  finally集合只为关闭资源

记住:finally很有用,主要用户关闭资源。无论是否发生异常,资源都必须进行关闭。

System.exit(0); //退出jvm,只有这种情况finally不执行。

 

当异常出现后,在子父类进行覆盖时,有了一些新的特点:

1:当子类覆盖父类的方法时,如果父类的方法抛出了异常,那么子类的方法要么不抛出异常要么抛出父类异常或者该异常的子类,不能抛出其他异常。

2:如果父类抛出了多个异常,那么子类在覆盖时只能抛出父类的异常的子集。

 

注意:

如果父类或者接口中的方法没有抛出过异常,那么子类是不可以抛出异常的,如果子类的覆盖的方法中出现了异常,只能try不能throws。

如果这个异常子类无法处理,已经影响了子类方法的具体运算,这时可以在子类方法中,通过throw抛出RuntimeException异常或者其子类,这样,子类的方法上是不需要throws声明的。

 

异常处理原则

1、函数内容如果抛出需要检测的异常(除开RuntimeException类及其子类),那么函数上必须要声明。否则必须在函数内部用try catch捕捉,否则编译失败。

2、如果调用到了声明异常的函数,要么try catch要么throws,否则编译出错

3、什么时候catch,什么时候用throws呢?功能内容可以解决,用catch。解决不了用throws告诉调用者。

4、一个功能如果抛出了多个异常,那么调用时,必须有对应多个catch进行针对性处理。内部有几个需要检测的异常,就抛几个异常,抛出几个,就catch几个。

 

异常注意事项

1、子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类。

class A extends Exception{}

class B extends A{}

class C extends Exception{}

class Fu{

void show() throws A{}

}

class Zi{

void show() throws A 或 不能是C

}

2、如果父类抛出多个异常,那么子类只能抛出父类异常的子集

 

常见异常:

1、脚标越界异常(IndexOutOfBoundsException)包括数组、字符串;

空指针异常(NullPointerException)

2、类型转换异常:ClassCastException

3、没有这个元素异常:NullPointerException

4、不支持操作异常;

异常要尽量避免,如果避免不了,需要预先给出处理方式。比如家庭备药,比如灭火器。

 

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------