第2课第5节_Java面向对象编程_异常_P

异常:程序在运行过程中发生由于外部问题(如硬件错误、输入错误)等导致的程序异常事件。(在Java等面向对象的编程语言中)异常本身是一个对象,产生异常就是产生了一个异常对象。异常(Exception)都是运行时的。编译时产生的不是异常,而是错误(Error)。需要注意的是,程序设计导致的错误(Error)不属于异常(Exception)。JAVA中异常都是从类Throwable类派生出来的,而Throwable类是直接从Object类继承而来,可见Java对异常处理的重视程度。
Error:系统内部错误,这类错误由系统进行处理,程序本身无需捕获处理;
Exception:可以处理的异常
RuntimeException:可以捕获,也可以不捕获的异常。
IOException:必须被捕获的异常。

java的异常处理的原则如下:

1、我们先写一个没有对异常处理的程序,在进行除法运算的时候,除数是非零的话,运行时没有问题的,但是除数为零的时候,运行就会有问题,程序也不能往下执行(只打印了Begin of div)

/* 下面程序的运行方式
 * java Div 6 2
 * 6/2=3
 */
public class Div{

    public static void main(String args[]){
        int m = Integer.parseInt(args[0]);//从字符串里面解析出整数
        int n = Integer.parseInt(args[1]);

        System.out.println("Begin of div");
        int r = div(m,n);
        System.out.println("end of div");

        System.out.println(m+"/"+n+"="+r);
    }

    public static int div(int m,int n){
        int r = m / n;
        return r;
    }
}

 

这里的“ArithmeticException”就是算数异常,属于 RuntimeException 这个运行异常(这个异常可以处理可以不处理,不处理程序会退出,但是编译是能够通过的),在进行处理时可以在本方法内自己进行处理,也可以抛出让调用者去处理,下面代码是本方法内进行处理的方式:

2、我们先写一个有对异常进行处理程序(自己处理异常),根据下面的运行结果,程序可以捕获到异常并且可以正常的执行.

public class Div2{

    public static void main(String args[]){
        int m = Integer.parseInt(args[0]);
        int n = Integer.parseInt(args[1]);

        System.out.println("Begin of div");
        int r = div(m,n);
        System.out.println("end of div");

        System.out.println(m+"/"+n+"="+r);
    }

    public static int div(int m,int n){
        int r = 0;
        try {/* try catch进行处理后程序在发生异常时就不会奔溃 */
            r = m / n ;
        }catch (ArithmeticException e){//捕获算数异常
            System.out.println(e);
        }finally{//加了 finally 无论是否发生异常都会执行这段代码
            System.out.println("This is finally of div");
        }
        /* 算数异常属于runtime异常可以处理也可以不处理,不处理就奔溃,但编译能通过 */
        return r;
    }
}

上面的程序在自己方法内进行处理,如果想让调用者处理,可以抛出这个异常,如下:

3、我们写一个程序将异常抛出的类,这个抛出的异常是由main进行处理.

public class Div4{

    public static void main(String args[]){
        int m = Integer.parseInt(args[0]);
        int n = Integer.parseInt(args[1]);
        int r = 0;

        System.out.println("Begin of div");
        try {/* 对异常进行处理 */
            r = div(m,n);
        }catch (ArithmeticException e){
            System.out.println(e);
        }
        System.out.println("end of div");

        System.out.println(m+"/"+n+"="+r);
    }

     /* 这里用 throws 把算数异常抛出给调用者*/
    public static int div(int m,int n) throws ArithmeticException{
        int r = 0;
        
        r = m / n ;

        return r;
    }
}

 4、如果在类的方法中如果处理了异常,那样在main方法中就不会对异常进行处理.

public class Div5{

    public static void main(String args[]){
        int m = Integer.parseInt(args[0]);
        int n = Integer.parseInt(args[1]);
        int r = 0;

        System.out.println("Begin of div");
        try {
            r = div(m,n);
        }catch (ArithmeticException e){
            System.out.println(e);
        }
        System.out.println("end of div");

        System.out.println(m+"/"+n+"="+r);
    }

    public static int div(int m,int n) throws ArithmeticException{
        int r = 0;

        try{
            r = m / n ;
        }catch(ArithmeticException e){
            System.out.println("div :"+e);
        }

        return r;
    }
}

5、如果在类的方法中如果处理了异常,同时在类方法中把异常抛出,那样main方法也可以捕获到异常.

如果这个异常想要本方法内处理一部分,也想让调用者也做处理的话,代码可以这样写:

public class Div6{

    public static void main(String args[]){
        int m = Integer.parseInt(args[0]);
        int n = Integer.parseInt(args[1]);
        int r = 0;

        System.out.println("Begin of div");
        try {
            r = div(m,n);
        }catch (ArithmeticException e){
            System.out.println(e);
        }
        System.out.println("end of div");

        System.out.println(m+"/"+n+"="+r);
    }
    /* 把异常丢给调用者处理,main里面如果不做处理也会奔溃 */
    public static int div(int m,int n) throws ArithmeticException{
        int r = 0;

        try{
            r = m / n ;
        }catch(ArithmeticException e){
            System.out.println("div :"+e);
            throw e;/* 这里要丢出异常main才会处理,否则调用者mian是捕捉不到这个异常的 */
        }

        return r;
    }
}

6、现在我们上面第5个例子的代码,只有对这种算术运行的异常进行处理,如果我传入的参数个数不对,还有参数的格式也不对,程序是处理不了的。

为了修复上述的问题,我们添加对传入参数格式不对,还有传入参数个数不对这两种异常的处理。

需要说明的是,对于“不可查的异常”, runtime 异常属于这个范畴,系统会自动抛出它,所以 div 方法后面的 throws 我们也可以不写。下面写一个同时捕获多个异常的程序,如下:

public class Div7{

    public static void main(String args[]){
        int m = 0;
        int n = 0;
        int r = 0;

        System.out.println("Begin of div");
        try {
            m = Integer.parseInt(args[0]);
            n = Integer.parseInt(args[1]);
            r = div(m,n);
             /* 当异常太多,每个都写太麻烦,可以捕获它们的父类 */
        }catch (ArithmeticException e){//算数异常
            System.out.println("main :" + e);
        }catch (NumberFormatException e){//数据格式异常
            System.out.println("main :" + e);
        }catch (ArrayIndexOutOfBoundsException e){//它们的父类,属于这个异常的子类都会被处理
            System.out.println("main :" + e);
        }
        System.out.println("end of div");

        System.out.println(m+"/"+n+"="+r);
    }
    /* 对于“不可查异常”, 系统也会抛出它,写不写后面这个throws效果一样 */
    public static int div(int m,int n) throws ArithmeticException{
        int r = 0;

        try{
            r = m / n ;
        }catch(ArithmeticException e){
            System.out.println("div :"+e);
            /* 这里执行throw之前会先去执行finally,但是如果finally它return了,
               这里就不会执行throw,会导致异常没有抛出 */
            throw e;
        }finally {
            System.out.println("finally of div");
            /* 这里不能 return */
            //return r;
        }

        return r;
    }
}

7、在第6个例子继续优化,上面的程序目前只能对算术运算、参数格式还有参数个数不对的异常进行处理,其他的情况是无法处理的到的,我们可以添加对这些异常的父类RuntimeException来捕获异常.

public class Div8{

    public static void main(String args[]){
        int m = 0;
        int n = 0;
        int r = 0;

        System.out.println("Begin of div");
        try {
            m = Integer.parseInt(args[0]);
            n = Integer.parseInt(args[1]);
            r = div(m,n);
        }catch (ArithmeticException e){
            System.out.println("main :" + e);
        }catch (NumberFormatException e){    //去掉了参数个数的异常,仍然可以捕获到
            System.out.println("main :" + e);
        }catch (RuntimeException e){
            System.out.println("main :" + e);
        }
        System.out.println("end of div");

        System.out.println(m+"/"+n+"="+r);
    }

    public static int div(int m,int n) throws ArithmeticException{
        int r = 0;

        try{
            r = m / n ;
        }catch(ArithmeticException e){
            System.out.println("div :"+e);
            throw e;
        }

        return r;
    }
}

8、对于“不可查异常”, 系统也会抛出它,写不写throws效果一样

public class Div9{

    public static void main(String args[]){
        int m = 0;
        int n = 0;
        int r = 0;

        System.out.println("Begin of div");
        try {
            m = Integer.parseInt(args[0]);
            n = Integer.parseInt(args[1]);
            r = div(m,n);
        }catch (ArithmeticException e){
            System.out.println("main :" + e);
        }catch (NumberFormatException e){
            System.out.println("main :" + e);
        }catch (RuntimeException e){
            System.out.println("main :" + e);
        }
        System.out.println("end of div");

        System.out.println(m+"/"+n+"="+r);
    }

    //public static int div(int m,int n) throws ArithmeticException{
    public static int div(int m,int n){
        int r = 0;

        try{
            r = m / n ;
        }catch(ArithmeticException e){
            System.out.println("div :"+e);
            throw e;
        }finally{
            System.out.println("finally of div");
        }

        return r;
    }
}

上面是属于runtime运行异常,可处理也可不处理,属于不可查异常范畴,下面是写一个可查的异常,即我们必须处理的异常,否则连编译都编译不过,程序如下:

public class Div9{
    public static void main(String args[]){
        int m = 0;
        int n = 0;

        int r = 0; 
        try {
            m = Integer.parseInt(args[0]);
            n = Integer.parseInt(args[1]);
            r = div(m, n);
        } catch (ArithmeticException e){
            System.out.println("main :"+e);
        } catch (NumberFormatException e){//数据格式异常
            System.out.println("main :"+e);
        } catch (RuntimeException e){//它们的父类
            System.out.println("main :"+e);
        } catch (Exception e){//捕获自己手工创建的可见异常,必须捕获并处理
            System.out.println("main :"+e);
        }

        System.out.println(m+"/"+n+"="+r);
    }

    /* 这里是“可查的异常”,所以如果div没有处理的话 throws 就必须写 */
    public static int div(int m, int n)throws Exception{
        int r=0;

        try {
            r = m / n;
        } catch (ArithmeticException e){
            System.out.println("div :"+e);
            /* 手工创建的可见异常,扔出去让别人处理 */
            throw new Exception("My Error");
        } finally {
            System.out.println("finally of div");           
        }

        return r;
    }
}

上面创建了可查的异常后,抛出来让调用者 main 来处理了,如果想自己处理了,就可以不用加 throws,如下:

    public static int div(int m, int n){
        int r=0;

        try {
            r = m / n;
        } catch (ArithmeticException e){
            System.out.println("div :"+e);
            try {
                throw new Exception("My Error");
            } catch (Exception e2){ //不抛出异常就得处理
                System.out.println("div :"+e2);         
            }
        } finally {
            System.out.println("finally of div");           
        }
        return r;
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值