初学 异常总结,异常finally执行顺序问题

来源:互联网 发布:淘宝自助开通账户网页 编辑:程序博客网 时间:2024/05/01 00:33

异常:

是在运行时期发生的不正常情况

Java发现不正常的情况都包含着一些常见信息,并 将这些信息进行了对象的封装。

异常这种机制,其实就是java按照面向对象的思想将出现的问题封装成了对象。

在进行问题分析时,发现问题有很多种,但是不断向上抽取,最终问题可以归纳为两种,一种是可以针对处理的一种是通常不进行处理的。

java中的体现一个是Exception ,一个是Error,后者一般针对处理。

无论是异常还是错误,他们都有名称信息等共性的内容。

可以继续抽取形成一个父类:throwable可抛出。

Throwable

|---Error

|---Exception

异常和错误都有一个特点:其子类的名称的后缀名都是父类名。

该体系具备一个特殊的特性叫做可抛性,该体系中的类可以被关键字throws抛出。

该体系中的类产生的对象可以被Throw抛出,简单说该体系可以被Throws throw操作。

Throw throws的区别:

Throws:定义在函数上,用于声明函数的可能出现的问题,后面跟异常类,可以跟多个,用逗号隔开、

Throw:定义在函数内,用于抛出异常对象因为程序的跳转,后面跟的是异常对象。

try{需要被检测的代码;}catch(异常类 变量){处理异常的代码(处理方式)} finally{一定会执行的语句:}

异常处理 代码详解:

class DemoDiv {int div(int x,int y){//【2】进行运算,一除就引发了问题(java虚拟机的算数问题return x/y;//把AritchmeticException()问题封装成了对象,并把这个问题抛给了调用这个问题的调用者,主函数 div(6,0)上}}class ExceptionDemo{//注:当没有检测到问题时,主函数没办法处理问题,给虚拟机处理,虚拟机采用默认处理,调用了默认的异常处理机制public static void main(String[] args) {//【1】首先在主函数在内存中建立了对象,当d对象调用了div函数把值传给了div x,yDemo d = new Demo();//try //【3】try尝试检测问题并检测到了,并把AritchmeticException()问题丢给了catch{int x = d.div(6,0);System.out.println("x="+x);//未执行}catch (Exception e)//【4】catch Exception e是Exception类型的引用变量   // => Exception e = new ArithmeticException();{System.out.println("除零了!");//【5】最后执行了处理代码,代表者问题被处理,没问题运行了}System.out.println("结束!");//【6】打印结束!}}

异常分两种:

1、编译被检测的异常:Exception

这种异常通常都需要进行针对性的处理。

2、运行时发生的异常:RuntimeException

对于运行时异常一般是不编写针对性的处理方式,如果该异常发生就让程序停止,

对程序进行修正。因为这种的出现往往已经无法让程序继续运算了。



class Demo{//在功能上通过throws的关键字声明了该功能有可能出现问题int div(int a,int b)throws ArithmeticException{if(b==0)throw new ArithmeticException("除数为零");return a/b;}}class ExceptionDemo3 {public static void main(String[] args) {getIndex(null,4);}public static int getIndex(int[] arr,int key){if(arr==null)//进行健壮性判断。throw new NullPointerException("没有具体的数组");for(int x=0;x<arr.length;x++){if(arr[x]==key)return x;}return -1;}public static int getElement(int[] arr,int index){if(arr==null)throw new NullPointerException("没有具体的数组实例");if(index<0||index>=arr.length)throw new ArrayIndexOutOfBoundsException("角标越界");return arr[index];}}


总结:

1、定义功能时,功能中有什么问题,都应该进行预先的处理比如try catch.如果处理不了,应该通过throws声明抛出,让调用者进行处理。

2、调用了抛出异常的功能的函数,应该进行处理,如果使用try catch处理的话,被调用的功能上抛出几个异常,就应该对应几个catch语句,必须要对多个异常进行针对性的处理。

3、如果出现多个catch中存在着父类异常的catch,那么这个catch一定放在catch的最后,通常这种情况在面试很多见。

4、如果函数内抛出异常,那么一定要在函数上声明,否则编译失败,但是要注意函数内抛出的异常是运行时异常(RuntimeException),那么函数上是可以不用throws声明的。

5、如果函数内抛出了异常,进行了本功能内部的处理,但是处理的并不完全,这时应该在异常处理中,继续将异常抛出,让在函数上声明让调用者知道问题的存在,但是有可能需要将异常进行转换,尽量抛出调用者识别的异常,处理起来更方便。

6、当子类覆盖父类中的异常声明的方法时,子类方法只能声明父类的异常或者该异常的子类。如果父类抛出了多个异常,那么子类在覆盖时买智能抛出父类异常的子集。

7、如果父类和接口中的方法没有声明抛出过异常,那么子类的覆盖父类方法时,也不能抛出异常,如果子类中的方法发生了异常,那么子类只能try catch不能用throws声明,只能try,不能抛,如果非要在函数内抛出异常,那么只能抛出RuntimeException,因为这种异常不用在函数声明上。

2、finally:

定义一定会被执行的代码。通常用来关闭资源,

异常处理的三种格式:

1、try catch finally

2、Try catch//可以多个catch

3、Try finally

记住:catch是用于处理异常的,如果没有catch就代表异常没有被处理过,如故哦该异常是检测时异常,必须被声明。


3、异常总结:

异常是什么?是对问题的描述,将问题进行对象的封装。

异常体系:

Throwable

|---Error

|--Exception

|--RuntimeException

异常体系的特点:

异常体系中的所有类以及建立的对象都具有可抛性。

也就说可以被throwthrows关键字操作。

只有异常体系具备这个特点。

Throwthrows的用法:

Throw定义在函数内,用于抛出异常对象。

Throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。

函数内有throw抛出异常对象,并未进行try处理必须要在函数上声明,否则编译失败, 注意:RuntimeException异常除外,也就说函数内如果抛出的是RuntimeException

函数上可以不用声明,如果函数声明了异常,调用者需要进行处理 吗,

处理方式throws也可以try

异常有两种:

1、编译时检测异常:

该异常在编译时如果没有处理,如果没有处理(没有抛也没有try)编译失败

2、运行时异常

在编译时,不需要处理,编译器不检查,该异常发生,建议不处理,让程序停止,需要对代码进行修正。

异常处理的语句:

try

{

需要被检测的代码

}

catch()

{异常处理代码}

fianlly

{一定会执行的代码}

有三种结合的格式:

1try{}catch(){}finally{}

2try{}catch(){}

3try{}finally{}

注意:

1finally中定义的通常是关闭资源,因为资源必须被释放。

2finally只有一种情况不会执行,当执行到System.exit(0);finally

不会执行。

5、自定义异常

   定义类继承Exception或者RuntimeException

   1、为了让该自定义类具备可抛性。

   2、让该类具备操作异常的共性方法。

   当要定义自定义异常的信息时,可以使用父类已经定义好的功能

   将异常信息传递给父类的构造函数,

 自定义异常:按照java的面向对象思想,将程序中出现的特有问题进行封装。

 

   异常的好处:

   1、将问题进行封装。

   2、将正常流程代码和问题处理代码相分离,方便阅读

  

  异常的处理原则:

  1、处理方式有两种:try 或者throws

  2、调用到抛出异常的功能时,抛出几个就处理几个。

     一个try对应多个catch的情况。

  3、多个catch父类的catch放到最下面。

  4catch内需要定义针对性的处理方式,不要简单的定义printStackTrace,输出语句。

  也不要不写。当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。

  try

  {

throw new AException

  }

  catch(AException e)

  {

throw e;

  }

  如果该异常处理不了,但并不属于该功能出现的异常,可以将异常转换后,在抛出和该功能相关的异常。

  或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,当调用者知道,并处理,也可以将捕获的异常处理后,转换新的异常。

  try

  {

throw new AException();

  }

  catch(AException e)

  {

throw new BException();

  }

  比如汇款的列子:

异常的注意事项:

在子父类覆盖时:

1、子类抛出的异常必须是父类异常的子类或者子集。

2、如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛。


/*证明return是在finally执行后才返回的,且在finally无法改变返回值。*/class FinallyTest{public static int demo(){int a = 1;try {System.out.println("try的 a:"+a);return a;//需要被检测的代码块}finally //一定会执行的语句{a=5;System.out.println("finally的 a:"+a);//return 15;}}public static void main(String[] args) {System.out.println("demo:"+demo());//调用demo,如果打印结果为1证明 finally不能改变try里面的返回值}}



	
				
		
原创粉丝点击