Java自学课程笔记5

2021年2月10日21点59分
JAVA自学课程笔记5:
    
    异常(Exception)
        当Java程序运行出现问题时,系统会自动检测到该错误,并立即生成一个与该错误对应的异常对象。    

        异常(Exception)的分类:
            Throwable(可抛出的):
                Error(系统错误,程序员无法处理这些异常)
                Exception(程序员可以捕获并处理的异常)
                RuntimeException(其子类所有的异常处理与否按需):
                    (其子类异常可处理可不处理)
        重写方法抛出异常的范围不能大于被重写方法抛出的异常的范围。(即子类抛出异常范围不能比父类大。)

        通过try-catch语句去捕获更正错误:
            class A{
                public int divide(int a, int b){
                    int ans = a / b;
                    return ans;
                }
            }

            public class Test1{
                public static void main(String[] args){
                    A aa = new A();
                    
                    try{
                        aa.divide(6, 0);
                    }catch(ArithmeticException e){        //e用来接收18行抛出的异常对象(算术异常)
                        System.out.printf("除零错误!除数不能为零!\n");
                    }

                    System.out.printf("You have excepted the error!\n");
                }
            }
        //输出结果:
            除零错误!除数不能为零!
            You have excepted the error!

        try语句只用于尝试不确定的语句,正确则运行,错误则被catch语句捕获并执行。若在try语句外出现错误,则仍会报错(相当于无视try后的源代码存在错误)。
            public class Test2{
                public static void main(String[] args){
                    int m;

                    try{
                        m = 2;
                        System.out.printf("m = %d\n", m);
                    }catch(Exception e){
                    }

                    System.out.printf("m = %d\n", m);    //若该行存在,则显示m未初始化;若该行不存在,则显示41行的m = 2。
                }
            }
        通过e.printStackTrace();语句可以将编译错误信息显示出来。
        ArrayIndexOutOfBoundsException(数组下标越界异常)。

        throw和throws:
            若出现异常(假设这里由throw抛出异常),则可用throws将异常抛出给上层引用者。
                import java.io.*;
                
                class A{
                    public void f() throws IOException{
                        throw new IOException();    //throw抛出异常
                    }
                }

                public class Test3{
                    public static void main(String[] args){        //若在主函数后添加"throws IOException"则不会出现68行情况。                                                  而会“直接报错”。因为异常从主函数抛给了虚拟机。
                        A aa = new A();
                        //aa.f();        若使用对象a的f()函数,则会直接报错说明“抛出的异常未被处理”。
                    }
                }

        try-catch语句中存在短路,若try有多条语句,则直接结束try语句跳转到catch。
        finally语句无论try语句中是否抛出异常,最终一定会执行。

        自定义异常:
            class NameException extends Exception{
                public NameException(String name){
                    super(name);
                }
            }

            class A{
                public int divide(int a, int b) throws NameException{
                    int m = 0;
                    if(b == 0)
                        throw new NameException("除数不能为零!\n");
                    else
                        m = a / b;
                    return m;
                }
            }

            public class Test4{
                public static void main(String[] args){
                    A aa = new A();
                    try{
                        aa.divide(6, 0);
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                }
            }
        //运行结果:
            NameException: 除数不能为零!

                at A.divide(test1.java:11)
                at test1.main(test1.java:22)


        建议在调用f()方法时对可能抛出的A异常进行捕捉(void f() throws A{}),其只是未雨绸缪的作用,且就算出现异常也不一定会对A异常进行捕捉(若异常为RuntimeException子类异常则不进行处理)。

        所有的catch语句只能有一个被执行。所以要遵循先catch子类异常再catch父类异常的规则的话,把catch子类语句写在catch父类语句之前。两条catch语句之间不能有任何别的代码。

        常见异常类型和说明:
            Exception
                异常层次结构的父类
            ArithmeticException
                算术错误情形,如以零作除数
            ArrayIndexOutOfBoundsException
                数组下标越界
            NullPointerException
                尝试访问null对象成员
            ClassNotFoundException
                不能加载所需的类
            IllegalArgumentException
                方法接收到非法参数
            ClassCastException
                对象强制类型转换出错
            NumberFormatException
                数字格式转换异常,如把"abc"转换成数字
        
        throw和throws的使用:
            public void dothing(int a,int b) throws Exception1,Exception3 {
                try{
                     //......
                }catch(Exception1 e){
                    throw e;
                }catch(Exception2 e){
                    System.out.println("自己打印提示,不抛出");
                }

                if(a!=b)
                    throw new  Exception3("自定义异常");
            }
        //代码块中try语句可能会产生3个异常,(Exception1,Exception2,Exception3)。
        //如果产生Exception1异常,则捕获之后再抛出,由该方法的调用者去处理。
        //如果产生Exception2异常,则该方法自己处理了(即打印出字符串:自己打印提示,不抛出)。所以该方法就不会再向外抛出Exception2异常了,void dothing() throws Exception1,Exception3 里面的Exception2也就不用写了(当然你写了也不会报错的),throws 就是声明可能抛出的错误,而Exception2 并未做出抛出操作。
        //而Exception3异常是该方法的某段逻辑出错,程序员自己做了处理,在该段逻辑错误的情况下抛出异常Exception3,则该方法的调用者也要处理此异常。

            class A extends Exception{}
            class B extends Exception{}
            class C extends Exception{}

            class M{
                void f() throws A,B{}
            }

            class N extends M{
                void f() throws A,B{}
            }

            class Test{
                public void k(M mm) throws A,B{
                    mm.f();
                }
            }

            class Test5{
                public static void main(String[] args) throws A,B{
                    M m = new M();
                    N n = new N();
                    
                    System.out.println("this");

                    Test aa = new Test();
                    aa.k(m);
                }
            }
        //运行结果:
            this

 

posted @ 2021-04-12 14:37  katachip  阅读(63)  评论(0编辑  收藏  举报