浅谈异常类

1.    异常由来:

问题也是现实生活中的一个具体事物,也可以通过程序进行描述,然后java类将其封装成对象。即把问题封装成对象。对于问题分两种情况,严重和不严重。严重则为Error类。非严重的java通过Exception类进行描述。当一个异常发生时,会有几件事随之而来,首先,像普通对象一样,通过new在堆上创建一个异常对象。然后当前程序的执行路径不能被继续下去,并且从当前环境中弹出异常对象的引用。此时异常处理机制接管程序,并开始寻找一个合适的地方去执行程序。这个恰当的地方就是异常处理程序,他使得程序从错误中出来,要么换种方式执行,要么继续执行。

2. 异常的体系:

       Throwable

                     Error:错误。通常出现重大问题,比如内存溢出,不编写代码针对其进行处理。

                     Exception:异常。程序在运行时出现的一些非正常情况。可以用try-catch-finally进行处理.

3.    对异常的处理

虚拟机内部有自己的异常处理机制:只要程序出现异常,就提前停止运行程序。Java提供了特有的语句进行处理。

Try(){

可能发生异常的代码块

}catch(异常类  变量){

        对异常的处理

}finally{

一定会执行的语句

}

现在用try—catch进行处理。

示例:

public class Exceptions {

    public staticvoid main(String[] args){

        int a=3;

       System.out.println("请输入一个整数");

        Scanner sc= new Scanner(System.in);

        int b =sc.nextInt();

        try{

        int c =a/b;  //输入的b假如是0,则会发生异常。

       System.out.println(c);

        }catch(Exception e[李艳1] ){

           e.printStackTrace();

        }

    }        

}

运行结果:

请输入一个整数

0

java.lang.ArithmeticException: / by zero

       atexception.Exceptions.main(Exceptions.java:22)

ArithmeticException: 计算异常。由此也可知,那句话发生了异常,则try中后边的代码不会再运行。

4.     打印异常信息的几种函数:

1>   getMessage()  这个函数只会获取到信息,但是不会打印出来,需要打印则需要用输出语句,比如:System.out.println(“e.getMessage()”) 打印异常信息。

示例:/ by zero

2>   getStackTrace():获取异常信息。[Ljava.lang.StackTraceElement;@4aa298b7

3>   printStackTrace():打印出异常信息,异常名称,异常发生位置。无需再次调用输出函数。其实默认的异常处理机制就是在调用该方法。

示例:java.lang.ArithmeticException:/ by zero

at exception.Exceptions.main(Exceptions.java:22)

4>   ToString():不常用,打印异常名称和异常信息。

示例:java.lang.ArithmeticException:/ by zero

5.     异常声明机制

你自己写的程序输入时知道传入0会有问题,但是别人用不知道,所以可能会传入0,故你需要给别人一个提示:也就是声明异常,告诉别人我这里可能有异常发生。这样别人就会注意。

声明方法:

        在功能上使用Throws的关键字声明了该功能可能会出现问题。

public static int div(int a,int b)throws Exception{

          int c =a/b;

          return c;

      }     

       告诉调用者,我这里有一个异常,让调用者自己选择处理不处理,可以处理(用try-catch),也可以直接抛给别人(继续在调用时选择throws,此时抛给了虚拟机)。但是如果两种方法都不选择,则编译失败。

6.     多异常处理

同一个代码可能不止发生一种异常。此时要对不同的异常进行处理。

可以在声明异常时抛出多个异常

1Throws异常名1,异常名2….异常名n

2》或者用多个catch进行捕捉,但是catch中必须写对应的处理。

尽量不要用异常父类直接进行捕捉,因为用父类捕捉,相当于隐藏问题,发生了问题但是没有进行处理,程序仍然在运行,相当于有个潜在的风险。

1>     建议声明更为具体的异常。这样才会处理的越具体。

2>     对方声明几个异常,就进行几个异常处理。

3>     先捕获子类,再捕获异类。就比如假设你让老大在前面,发生的问题大哥都搞定了,小弟的存在就是多余,所以应该先让小弟处理,再找大哥。

7.     自定义异常:

Java中会出此案一些特定的问题,而这些问题并未被java描述并且封装成对象,对于这些特有问题,可以按照java封装思想,可以将其封装成自定义异常。

如何自定义异常?

需求:做一个除法运算,除数为零和负数都不可以。为0的情况已经被Java封装,所以为负数的情况需要自己定义一个类,对这个问题进行描述。

定义异常类:一般是描述问题方法+Exception后缀名。有了名字后,还需要入伙,这样才能算是异常中的一个成员,故所有自定义异常都需要继承Exception类。当函数内部出现了throw抛出了异常对象,则必须给出对应的处理动作。要么在内部try-catch,要么在函数上声明,让调用者处理。一般函数内出现异常,函数上需要给出声明。

如何自定义呢?父类已经完成了异常信息的操作,子类构造时只需通过getMessage()获取异常信息即可。

示例:

class FushuException extends Exception{

    private intvalue;

   FushuException(String msg,int value){

     super(msg);

     this.value = value; //获取到出错的值

    }

 

    public intgetValue() {

        returnvalue;

    }

   

}

class Demo{

    int div(int a,int b) throws FushuException{

        if(b<0){

            thrownew  FushuException("除数不能为负数",b);

        }

        return a/b;

    }

}

8.     throwsthrow的区别:

1.     throw使用在函数内,throws使用在函数上。

2.     throws后跟异常类,用逗号隔开。Throw跟的时异常对象。

Throw是用来异常说明的,为了让调用者知道这里可能发生异常。。

9.运行时异常(RuntimeException

       如果在函数内容上抛出此异常,函数上不用声明,编译也可以通过。如果在函数上声明了该异常,调用者可以不用处理,编译一样通过。之所以不用声明,是不希望调用者处理,一旦发生问题,就希望程序停下来,修改代码解决问题,而不是将问题隐藏。这样看来,如果你自定义一个异常而不向声明时,可以让他继承RuntimeException类。因为运行时异常类java虚拟机已经默认声明了。

/*

 * To change thislicense header, choose License Headers in Project Properties.

 * To change thistemplate file, choose Tools | Templates

 * and open thetemplate in the editor.

 */

 

package exception;

 

import java.util.logging.Level;

import java.util.logging.Logger;

 

/** 为一个类定义两个方法f()g(),在g里抛出一个自定义异常,然后在f里调用g

 *  然后捕获异常,并且在catch里抛出另一个异常,在main中测试该异常。

 *

 * @author dell

 */

public class Two {

    public staticvoid main(String[] args) {

        try {

            Two x =new Two();

            x.f(3);

           x.g(-1);

        } catch(AException ex) {

           ex.printStackTrace();

        } catch(BException ex) {

           Logger.getLogger(Two.class.getName()).log(Level.SEVERE, null, ex);

        }

    }

   

    //定义方法

    void g(int a) {

        if(a<0)

            thrownew AException("参数不可以小于0");

    }

   

    void f(int b){

        Two two =new Two();

        try {

            two.g(b);

        } catch(AException ex) {

           ex.printStackTrace();

            thrownew BException("都说了参数不能为0");

        }

    }

}

//异常1

class AException extends RuntimeException{

 

    publicAException(String msg) {

        super(msg);

    }

   

}

 

//异常2

class BException extends RuntimeException{

 

    publicBException(String message) {

       super(message);

    }

   

}

10 使用finally进行异常清理

       对于一些代码,很多时候,无论异常是否发生,都希望执行,经常适用于内存回收之外的情况(因为内存回收由虚拟机执行)。对于这部分代码,可以将其放在finally块中执行。

Finally用来做什么?

对于没有垃圾回收机制的语言中,finally显得尤为重要,但是java有这个机制,所以不需要考虑回收内存。但是对于释放资源,或者关闭一些链接之类的东西,需要用到finally块,比如你打开一个文本文件,在里边写东西,当然希望无论你写入成功失败,都必须保证在main方法结束时可以关闭文件夹,这样就可以把关闭的代码放在finally中。当涉及到breakcontinue语句时,finally也会被执行。

try {

            Two x =new Two();

            for(inti=0;i<=0;i++){

               break;

            }

            x.f(3);

           x.g(-1);

        } catch(AException ex) {

           ex.printStackTrace();

        } catch(BException ex) {

           Logger.getLogger(Two.class.getName()).log(Level.SEVERE, null, ex);

        }finally{

           System.out.println("finally块被执行了");

        }

执行可发现,还是会执行finally中的。


 [李艳1]这句被执行其实是相当于:Exceptione = new ArithmeticException()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值