(35)异常

来源:互联网 发布:java流程引擎activity 编辑:程序博客网 时间:2024/06/11 11:37

一、异常概念

①异常:程序在运行时出现不正常的情况

②异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象

③对于问题的划分:两种:一种是严重的问题,一种是非严重的问题。

    对于严重的,java通过Error类进行描述,对于Error一般不编写针对性的代码对其进行处理

    对于非严重的,java通过Exception类进行描述,对于Exception可以使用针对性的处理方式进行描述

无论Error或者Exception都具有一些共性内容

比如:不正常情况的信息,引发原因等。

Throwable

    ------Error

    -----Exception

二、异常的处理

java提供了特有的语句进行处理

try{  需要被检测的代码  }

catch(异常类 变量)

   {处理异常的代码  }

finally{一定会执行的语句 }

对这些语句执行流程有个简单的了解:举个栗子

若执行程序,不出异常,则会把try执行完,不会执行catch


       public int div(int a,int b) {return a/b;//出现问题:new AritchmeticException()[封装成一个对象]}public static void main(String[] args) {        Demo d=new Demo();        try {        int x=d.div(4, 0);//在div方法执行过程中出现了问题,并把这个问题抛给调用者:d.div(4, 0),因为有try检测机制,                           // 所以,就检测到问题了。并且将这个问题丢给catch,出现问题之后的语句就不执行了,                                  System.out.println("x="+x);        }        catch(Exception e)//怎么接收到的呢?Exception e=new AritchmeticException();接收到,就执行处理代码                          //问题检测到,并处理了,所以System.out.println("over");执行了        {        System.out.println("出现异常了");        }        System.out.println("over");        }


三、异常中catch常见的处理方法:

getMessage

public String getMessage()
返回此 throwable 的详细消息字符串。

返回:
Throwable 实例(可以为 null)的详细消息字符串。

toString

public String toString()
返回此 throwable 的简短描述。结果是以下字符串的串联:
  • 此对象的类的 name
  • ": "(冒号和一个空格)
  • 调用此对象 getLocalizedMessage() 方法的结果
如果 getLocalizedMessage 返回 null,则只返回类名称。
覆盖:
Object 中的toString
返回:
该 throwable 的字符串表示形式。

printStackTrace

public void printStackTrace(PrintWriter s)
将此 throwable 及其追踪输出到指定的 PrintWriter。

参数:
s - 用于输出的 PrintWriter



             catch{        System.out.println(e.getMessage());//  /by zero        System.out.println(e.toString());//异常名称:异常信息[java.lang.ArithmeticException: / by zero]        System.out.println();                e.printStackTrace();//异常名称,异常信息,异常出现的位置                                //jvm默认的异常处理机制,就是在调用printStackTrace()方法                                //打印异常堆栈 的跟踪信息                                 /*                                  *                                   java.lang.ArithmeticException: / by zero                               at Demo.div(Demo.java:5)                               at Demo.main(Demo.java:11)                                }


四、throws Exception:对有可能出现问题的方法后面标识

便于提高安全性,让调用进行处理,不处理编译失败


public int div(int a,int b)throws Exception /*   有时调用者可能发现不了这个函数在调用时,会出现问题,   所以,在编写函数时,在功能上通过throws的关键字声明了该功能有可能出现问题   这样,在直接调用这个函数时,系统就会提示程序员应该写trycatch语句①或者继续抛出异常②,避免一些异常的发生 */{return a/b;//出现问题:new AritchmeticException()[封装成一个对象]}写法一①public static void main(String[] args) {// TODO Auto-generated method stubDemo1 d=new Demo1();try {int x=d.div(4, 0);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}      写法二②主函数抛出异常,jvm进行处理,jvm默认的异常处理机制,就是在调用printStackTrace()方法,jvm处理异常,              程序也就结束了,出现异常后的语句,不再执行             public static void main(String[] args) throws Exception {        // TODO Auto-generated method stub        Demo1 d=new Demo1();        d.div(4, 0);            }


五、对多异常的处理

①声明异常时,建议声明更为具体的异常。这样处理的可以更具体。在四中只是throws Exception,并没有明确这个异常是哪种类,型,所以应声明饿更具体些。

②对方声明几个异常,就对应有几个catch块,不要定义多余的catch块

  如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面

建议在catch处理时,catch中一定要定义具体的处理方式。

不要简单定义一句e.printStackTrace(),也不要简单的就书写一条输出语句(这语句没啥意义,异常还是没有解决)



public class Demo2 {public int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException/* * 注意一个函数段可能会发生多个异常,可以抛出多个异常,但是不可能这些异常都被catch到,至多catch一个 * 原因是在函数中,出现异常,就会立刻返回到被调用者处,此函数之下的都不会被执行了,进而catch捕获到异常 * 执行catch后的语句. */{int[] arr=new int[a];System.out.println(arr[4]);return a/b;//出现问题:new AritchmeticException()[封装成一个对象]}public static void main(String[] args) {// TODO Auto-generated method stubDemo2 d=new Demo2();try {int x=d.div(4, 0);System.out.println("x="+x);}catch(ArrayIndexOutOfBoundsException e) {System.out.println("角标越界"+e.toString());}catch(ArithmeticException e){System.out.println("被零除"+e.toString());}System.out.println("over")}



六、自定义异常

因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象。

所以对于这些特有的问题乐可以按照java的对问题封装的思想。

将特有的问题,进行自定义的异常封装。


当在函数内部出现了throw抛出异常对象,那么必须要给出对应的处理对象。throw new FuShuException("除数不能为负数啊!!");

要么在内部try catch处理,要么在函数上声明让调用者处理。

一般情况下,函数出现异常,函数上需要声明(throws 自定义异常类)【在调用者处用try catch或者继续抛出异常】

发现打印的结果只有异常的名称,却没有异常的信息。因为自定义的异常并未定义信息。

如何定义异常的信息呢?


方法一:

首先看throwable中构造函数:Throwable(String message)

然后看方法摘要中有个String getMessage()方法

所以想到在自定义异常类中进行复写



自定义异常类:public class FuShuException extends Exception {private String message;FuShuException(String message){this.message=message;}public String getMessage() {return message;}}public class Demo3 {public int div(int a ,int b) throws  FuShuException(声明){    /*     * 自定义异常,需要抛出异常的相应的对象(catch里面接收的就是异常的对象),然后抛出     */    if(b<0) {            throw new FuShuException("除数不能为负数啊!!");            }    return a/b;}    public static void main(String[] args) {        // TODO Auto-generated method stub     Demo3 d=new Demo3();     try {     int x=d.div(4, -1);         }     catch( FuShuException e) {         System.out.println(e.toString());//输出:com.YiChang.FuShuException: 除数不能为负数啊!                                           //toString自动调用FuShuException类中的getMessage方法     }}} 


方法二、根据继承中函数的特点,来写自定义异常类中的内容(这个是书写自定义异常类内信息的简洁方式)

   在子异常类中调用父类的构造方法super(message)

  这个子异常类中,还有个默认继承过来的getMessage方法,所以不用写这个方法了

简单来说:因为父类中已经把异常信息的操作都完成了。所以子类只要在构造函数是,将异常信息传递给父类通过super语句。

那么就可以直接通过getMessage方法获取自定义的异常信息



public class FuShuException extends Exception {private String message;FuShuException(String message){     super(message);}}


对上面异常的描述更具体些:


public class FuShuException extends Exception {    private String message;    private int value;//具体哪个数是异常的    FuShuException(String message,int value ){         super(message);         this.value=value;    }    public int getValue() {        return value;    }    }public class Demo3 {public int div(int a ,int b) throws  FuShuException{/* * 自定义异常,需要抛出异常的相应的对象(catch里面接收的就是异常的对象),然后抛出 */if(b<0) {throw new FuShuException("除数不能为负数啊!!",b);}return a/b;}public static void main(String[] args) {// TODO Auto-generated method stub     Demo3 d=new Demo3();     try {     int x=d.div(4, -9);     }     catch( FuShuException e) {     System.out.println("格式:异常类名:具体异常      "+e.toString());     System.out.println("异常数据是:"+e.getValue());//输出:9         }}}



自定义异常:

必须是自定义类继承Exception.

继承Exception类的原因:

异常体系有一个特点:因为异常类和异常对象都可抛出。

他们都具有可抛性,这个可抛性是Throwable这个体系中独有的特点。

只有这个体系中的类和对象才可以被Throws和throw操作

不是任意的类和对象可抛出的

七、throws 和throw区别

①位置:throws使用在函数上,throw使用在函数内

②throws后面跟的是异常类,可以跟多个,用逗号隔开

   throw后面跟的是异常对象














原创粉丝点击