• Java基础系列四、异常处理


    1、异常顶层父类~Throwable类

      Throwable类是Java异常类型的顶层父类,Throwable又派生出Error类和Exception类。

      错误:Error类   以及他的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。

      异常:Exception类   以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。

    2、运行时异常、非运行时异常

      根据Javac对异常的处理要求,将异常类分为2类。

        非检查异常(unckecked exception)也叫运行时异常:即编译时不会产生异常,运行产生异常。Error 和 RuntimeException 以及他们的子类。。这样的异常发生的原因多半是代码写的有问题。如除0错误ArithmeticException,

      错误的强制类型转换ClassCastException,数组索引越界ArrayIndexOutOfBoundsException,使用了空对象NullPointerException等等。

        检查异常(checked exception)也叫非运行时异常:即不管你代码写的正确与否,你都要进行处理,因为JVM认为你这段代码产生的异常的概率大。本质:是因为你调用的那些方法在底层实现时就抛出了异常。。除了Error 和 RuntimeException的其它异常。javac强制要求程序员为这样的异常做预备处理工作(使用try…catch…finally或者throws)。

    如SQLException , IOException,ClassNotFoundException 等。

    3、异常处理语法

      1.、对于检查异常,有2种不同的处理方式:使用try…catch…finally语句块处理它。或者,在函数签名中使用throws 声明交给函数调用者caller去解决。

      2、注意点:

        1、try块中的局部变量和catch块中的局部变量(包括异常变量),以及finally中的局部变量,他们之间不可共享使用。

        2、 try块中存放放可能产生异常对象的代码,如果检测 try块中代码不产生异常,就不会执行catch块代码。否则,当try代码块产生异常对象时,会自动执行catch代码块,并且将异常对象传递给参数 e.

        3、try{}代码块产生的异常一定要是catch中参数的 真正异常的类型 或者是其 子类

        4、 每一个catch块用于处理一个异常。异常匹配是按照catch块的顺序从上往下寻找的,如果同一个try块下的多个catch异常类型有父子关系,异常子类 要放在 异常父类 的前面.

         如果所有的catch都抓不住,可能就相当于我们没有处理到,又可能由JVM处理

        5、finally块不管异常是否发生,只要对应的try执行了,则它一定也执行。只有一种方法让finally块不执行:System.exit()。

         因此finally块通常用来做资源释放操作:关闭文件,关闭数据库连接等等。良好的编程习惯是:在try块中打开资源,在finally块中清理释放这些资源。

        6、 try{}catch{}   ,  try{} finally{}  ,  try{}catch{}finally{} 这三种写法是正确的。

    4、获取异常信息的方法

         Throwable父类中  常用的三个方法 用来获得对象中的异常描述信息

          try{
                System.out.println(10/0);
            }catch (ArithmeticException e) {
                //  e.printStackTrace();             //打印异常对象  堆栈详细信息 ,
                System.out.println(e.getMessage()); //获取错误信息
                System.out.println(e.toString());  //返回此 throwable 的简短描述 
            }
    
    / by zero
    java.lang.ArithmeticException: / by zero
    

    5、常见的异常类

    public static void main(String[] args) {
            //多重异常捕获(多重catch块):对产生的异常对象逐个去进行匹配,直到匹配成功为止
            //注意  异常子类  要放在  异常父类  的前面
            try {
                Integer a = new Integer("aa你好");
            }
            catch (NullPointerException e) {
                System.out.println("空指针异常");
            } 
            catch (ArithmeticException e) {
                System.out.println("算术异常");
            } 
            catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("数组索引越界异常");
            } 
            catch (ClassCastException e) {
                System.out.println("类型转换异常");
            }
            catch(NumberFormatException e){
                System.out.println("数字格式异常");
            }
            catch (Exception e) {
                System.out.println("你是个异常,我就能治好你");
            }
         finally{
          System.out.println("只要执行了try块,我总会执行");
         }
            System.out.println("end");
        }
    结果:   
    数字格式异常
    只要执行了try块,我总会执行
    end
    

      

    6、自定义异常   

     如果要自定义异常类,则扩展Exception类即可,因此这样的自定义异常都属于检查异常(checked exception)。如果要自定义非检查异常,则扩展自RuntimeException。

    throw、throws的区别 

      throw  用来创建异常对象,在方法里面, 后面只能够跟一个具体的异常对象

      throws  用来申明我这个方法中的某段代码有异常。 在方法签名后面,即在() {}之间,    后面跟多个异常类型

    package cm.异常处理;
    /*  自定义异常的流程  :下面是第一步:
     * ① 自定义一个类
     * ② 继承 Exception 或者 RuntimeException
     * ③ 提供一个公共无参数的构造方法和一个String参数的构造方法
     */
    public class MuException extends Exception {
        private static final long serialVersionUID = 1L;
        
        public MuException() {
            super();
        }
        public MuException(String message) {
            super(message);
        }
    }
    package cm.异常处理;
    /*
     * 第二步: 设计一个注册Register的方法,根据条件判断在适当的时候抛出(产生)一个上面1的异常对象,抛出去。
     */
    public class Register {
        private static String[] users = { "小王", "小李", "小明" };// 写一个数组,模拟已经注册的用户
        //注册用户名的方法
        public static void register(String userName) throws MuException{
            for(int i=0;i<users.length;i++){
                // 条件判断,如果用户名不为空,且已经存在,则抛出一个MultipleException异常
                if(userName!="" && userName.equals(users[i])){
                    // throw:在方法里向调用者抛出异常
                    throw new MuException("亲,用户名:" + userName + "已经注册,请重新输入!");
                }
            }
            //没有重复,则注册成功
            System.out.println("恭喜你,注册成功!玩的开心!!");
        }
    }
    package cm.异常处理;
    
    public class TestRegister {
    
        public static void main(String[] args) {
            try{
                Register.register("哈哈");
            }catch(MuException e){
                e.printStackTrace();
            }
            
            try{
                Register.register("小王");
            }catch(MuException e){
                e.printStackTrace();
            }
        }
    
    }
    
    结果;
    恭喜你,注册成功!玩的开心!!
    cm.异常处理.MuException: 亲,用户名:小王已经注册,请重新输入!
    at cm.异常处理.Register.register(Register.java:13)
    at cm.异常处理.TestRegister.main(TestRegister.java:14)
    

      

  • 相关阅读:
    用Python抓取并分析了1982场英雄联盟数据,教你开局前预测游戏对局胜负!
    初级练手项目——用Python一步一步实现“智能”贪吃蛇!
    这五本Python急速入门必读的书,送给正在学习Python的你!
    探讨2018年最受欢迎的15顶级Python库!
    运用Python制作你心目中的完美女神脸!
    掌握这些Python代码技巧,编程至少快一半!
    解决Protege使用中的一个问题:从已有owl文件建立项目失败(w3china)
    http响应状态码
    云计算二 转帖
    protege中Property Domains and Ranges理解
  • 原文地址:https://www.cnblogs.com/gshao/p/10073325.html
Copyright © 2020-2023  润新知