java笔记13 异常

来源:互联网 发布:linux c 获取文件路径 编辑:程序博客网 时间:2024/05/16 12:58

1. 异常概述

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

 

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

 

1.3异常体系

--------java.lang.Throwable:

Throwable:可抛出的。

         |--Error:错误,一般情况下,不编写针对性的代码进行处理,通常是jvm发生的,需要对程序进行修正。

         |--Exception:异常,可以有针对性的处理方式

 

1.4  特点

1、无论是错误还是异常,它们都有具体的子类体现每一个问题,它们的子类都有一个共性,就是都以父类名作为子类的后缀名

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

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

2. Throwable中的方法:
1、getMessage():获取异常信息,返回字符串。
2、toString():获取异常类名和异常信息,返回字符串。
3、printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void。
4、 printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查阅。

备注:jvm默认的异常处理机制,就是在调用printStackTrace方法,打印异常的堆栈跟踪信息

 

3. 异常的处理

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

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

try{

    需要被检测的代码;

}

catch(异常类 变量名){

    异常处理代码;

}

fianlly{

    一定会执行的代码;//除非出现System.exit(0),jvm关闭

}

2、抛出:用throws向上抛出,交给上一级调用者处理,最终交给虚拟机,虚拟机也不能处理,强行中止。

 

4. 异常的分类

4.1异常分两种:

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

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

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

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

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

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

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

 

5. 异常处理的原则

1、函数内容如果抛出需要检测的异常,那么函数上必须要声明。

否则,必须在函数内用try/catch捕捉,否则编译失败。

2、如果调用到了声明异常的函数,那么try/catch,要么throws,否则编译失败。

3、什么时候catch,什么时候throws呢?
功能内容可以解决,用catch。

解决不了,用throws告诉调用者,由调用者解决。

4、一个功能如果抛出了多个异常,那么调用时,必须有对应多个catch进行针对性处理。

内部有几个需要检测的异常,就抛几个异常,抛出几个,就catch几个。

    需要注意的是:try对应多个catch时,如果有父类的catch语句块,一定要放在下面。

    如果放在第一个,父类被处理了,子类就不会被处理。

 

6. 自定义异常

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

6.2自定义异常的步骤:

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

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

public class H_09ZiDingYiException{         public static void main(String[] args)         {                            Div2 d=new Div2();                            try                            {                            intx=d.div(4, -1);                            }                            catch (FuShuExceptione)                            {                                               System.out.print(e.toString());                            }                   }}class FuShuExceptionextends Exception{                   FuShuException()                   {                            super();                   }                   FuShuException(String msg)                   {                            super(msg);                   }} class  Div2{                   int  div(inta,intb) throws FuShuException                   {                                     if(b<0)                                                        thrownew FuShuException("出现了除数是负数的问题");//手动通过throw关键字抛出一个自定义异常                                     returna/b;                   }}

结果:FuShuException: 出现了除数是负数的问题

 

7. throw和throws

1、throw定义在函数中,可以在try括号内也可以在catch括号内,明确地抛出一个异常对象

需要注意的是,不要在throw语句下写其他语句,会因为不能执行到而报错。

2、throws定义在函数上,用于明确这个函数可能抛出的异常类,可以接多个异常类,用逗号隔开。

3、用throw抛出一个明确的异常,则函数上也必须用throws抛出同样或者其父类的异常。

例外:RuntimeExcepiton 可以中断程序而不在函数上抛出

4、在继承的情况下,如果父类没有抛出异常,那么子类只能使用try catch处理,不能抛出异常。

 

8. trycatch finally 代码块组合特点:
1. try catch finally
2. try catch(多个)当没有资源需要释放时,可以不用定义finally。
3. try finally 异常无法直接catch处理,但是资源必须关闭。

 

9. finally测试

public class Test6{         public static void main(String[] args)         {                   //调用exceptionTest方法接收返回值                   int num=exceptionTest();                   System.out.println(num);         }         public static int exceptionTest()         {                   try                   {                            return 1;                   }                   catch(Exception e)                   {                            throw new RuntimeException("返回错误");                   }                   finally                   {                            System.out.println("finally执行了");                            //return 2;finally语句中不要加return                   }                         }}

结果:finally执行了

      1

    结果分析:

    代码其实是按顺序执行的,在得到return的返回值后,finally语句也执行了。说明retrun不会影响finally语句的执行。

但因为返回值需要另外接收,所以只能接收后再打印出来。

需要注意的是:在finally语句中不要加return语句,一方面会覆盖前面代码return的结果,一方面会导致接收不到前面抛出的异常。


0 0