zoukankan      html  css  js  c++  java
  • Java之初学异常

    异常

    学习异常的笔记记录

    异常

    异常的概念

    指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。

    异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.

    异常的体系

    异常体系

    简单划分下 :

    Throwable : java语言中所有异常和错误的超类
        |-- Exception : 编译期异常(日期格式化,日期解析,需要try-catch/throws抛出)
            |--RuntimeException : 运行期异常(数组越界异常)
        |--Error : 错误(数组创建长度过大)
    

    异常(Exception)的分类

    • 编译期异常 :在编译时期就要处理(IO流的文件不存在,日期解析格式化),不处理便已不能通过
    • 运行期异常 : 在运行时出现的异常(/by zero,索引越界等等)

    举个例子(异常是怎么产生的和产生后如何处理) :
    异常产生

    异常的处理

    throw 关键字:

    • 作用 : 可以使用throw关键字在指定的方法中抛出异常
    • 使用格式 : throw new xxxException("异常产生的原因"");

    1.throw new 必须写在方法的内部
    2.throw new 后面的对象必须是Exception类或者是Exception的子类对象
    3.throw抛出RuntimeException或者它的子类,可以不处理,交给JVM处理.
    抛出编译异常,就必须处理该异常,try{}catch{}或者throws

    throws 关键字:

    • 作用 : 当方法内部抛出异常对象的时候,处理时可以使用throws抛出给调用者,让调用者处理.

    • 使用格式 : 在方法声明时在最后使用throws抛出

        修饰符 返回值类型 方法名(参数列表) throws xxxException{}
      

    1.throws关键字必须写在方法声明处
    2.throws关键字后边声明的异常必须是Exception或者是他的子类
    3.方法内部如果抛出多个异常,throws也必须写多个异常,存在父子关系的,可以直接写父类,如果都写子类必须在父类的前面
    4.调用方法处理时,可以继续使用throws,也可以try{}catch{}

    throw与throws的区别 :

    • 位置不同,前者方法中,后者方法声明处
    • 含义不同,前者制造异常,后者是处理异常
    • 格式不同,throw + 异常对象,throws + 异常名称(多个异常,使用逗号隔开就好)

    try..catch..:

    • 格式 :

        try{
            可能出现问题的代码
        }catch(异常类型 变量名){  // 声明异常变量
            处理异常的代码  // 尽量不要只用printStackTrace() 处理
        }
      
    • 执行流程 : try内代码出现异常,catch会捕获异常(使用catch中的类型进行匹配,匹配成功之后就会执行catch内的代码
      如果匹配失败,则继续向上抛出,交给调用者去处理,最后都没有处理时会交给JVM进行处理),try出现异常的地方后面的代码
      停止执行,执行catch内的代码,如果try内没有出现异常代码正确执行,不会执行catch的代码.

    try...catch..finally :

    • 当程序出现一种需求,无论程序是否出现异常,都需要执行某个代码块(比如流的关闭,sql连接关闭等等),这个时候就需要finally了

    • 格式 :

        try{
            可能出现异常的代码
        } catch(异常类型 变量名){
            异常处理
        } finally{
            无论是否出现异常都需要执行的代码
        }
      
    • 执行流程 : 在try..catch的基础上,catch执行完毕或者JVM处理完异常之后,执行finally代码块,除非使用System.exit(0)强行停止代码.

    不要再finally中使用return语句,虽然语法上无错误,但尽量避免,finally语句一般用于回收资源,
    如果在try或catch中进行一个返回值.这个时候这个返回通道的值已经确定,在finally语句中修改值,这个
    时候返回值并不会被修改.

    举个例子,用来说明上面那个返回通道的问题:

    Throwable类定义了处理异常的三个方法:

    • public String getMessage() :获取异常的描述信息,原因(提示给用户的时候,就提示错误原因。
    • public String toString() :获取异常的类型和异常描述信息(不用)。
    • public void printStackTrace() :打印异常的跟踪栈信息并输出到控制台。

    多个异常如何处理:

    • 多次捕获,多次处理(也就是每个可能出现异常的代码都使用一个try..catch进行捕获处理)
    • 一次捕获,多次处理(也就是一个try,多个catch,注意的是catch中有子父类关系,子类异常必须在父类异常的前面)
    • 一次捕获,一次处理(也就是catch中使用具有较高父类的Exception对象)(建议使用)

    举个例子:

    public class TryCatchDemo {
    
        public static void main(String[] args) {
    
            // 多个异常多个处理
            try {
                // 产生空指针异常(创建对象赋值为null,使用对象调用方法可以产生空指针异常)
                Integer integer = null;
                System.out.println(integer.toString());
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
            // 出现的顺序很奇怪,正好体现的是多线程
            try {
                // 产生字符串越界异常,访问字符串的索引查过字符串的长度就可以产生
                String s = "dilireba";
                for(int i = 0; i <= s.length(); i++){
                    System.out.println(s.charAt(i));
                }
            } catch (StringIndexOutOfBoundsException e) {
                e.printStackTrace();
            }
    
            // 多个异常一次捕获,多次处理
            try {
                // 产生空指针异常(创建对象赋值为null,使用对象调用方法可以产生空指针异常)
                Integer integer = null;
                System.out.println(integer.toString());
                // 产生字符串越界异常,访问字符串的索引查过字符串的长度就可以产生
                String s = "dilireba";
                for(int i = 0; i <= s.length(); i++){
                    System.out.println(s.charAt(i));
                }
                // 会出现NullPointerException,因为第一次异常之后后面的代码停止执行
            } catch (NullPointerException e) {
                e.printStackTrace();
            }catch (StringIndexOutOfBoundsException e) {
                e.printStackTrace();
            }
    
            // 多个异常一次捕获,一次处理,建议使用这种
            try {
                // 产生空指针异常(创建对象赋值为null,使用对象调用方法可以产生空指针异常)
                Integer integer = null;
                System.out.println(integer.toString());
                // 产生字符串越界异常,访问字符串的索引查过字符串的长度就可以产生
                String s = "dilireba";
                for(int i = 0; i <= s.length(); i++){
                    System.out.println(s.charAt(i));
                }
            } catch (Exception e) { // 实际上是使用了多态
                // 会出现NullPointerException,因为第一次异常之后后面的代码停止执行
                e.printStackTrace();
            }
        }
    }
    

    异常的注意事项:

    1.如果父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集。
    2.父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不
    能声明抛出

    3.运行时异常被抛出可以不处理。即不捕获也不声明抛出。
    4.在try/catch后可以追加finally代码块,其中的代码一定会被执行,通常用于资源回收。
    5.如果finally有return语句,永远返回finally中的结果,避免该情况.

    自定义异常

    Java提供的异常类,有时候对于我们来说不够用,做不到见名知意,这个时候需要自定义异常类

    • 格式 :

        public class XXXException extends Exception | RuntimeException{
            添加一个空参数构造方法
            添加一个带异常信息的构造方法
        }
      
    • 注意 :
      1.自定义异常一般都是以Exception结尾的,说明该类是一个异常类
      2.自定义异常类,必须继承Exception或者是RuntimeException,前者用于自定义编译期异常,后者用于自定义运行期异常(可以不处理,交给JVM处理).

      如下所示,自定义异常类:

        /**
         * 自定义异常类,在进行开发的时候一定要做到见名知意
         *
         * @author WZLOVE
         * @create 2018-07-16 15:53
         */
        public class MyException extends Exception{  // 自定义编译期异常类,继承Exception类,重写两个构造方法
        
        
            public MyException() {
            }
        
            public MyException(String message) {
                super(message);
            }
        }
      

    可以尝试着自己写一个注册的异常类,尝试一下.

  • 相关阅读:
    Activity 横竖屏生命周期
    gradle wrapper, gradle ,gradle plugin 之间的关系
    《构建之法》第八、九章学习总结
    《构建之法》第六、七章学习总结
    《构建之法》第三、四、五章学习总结
    《构建之法》第一、二章学习总结
    SQL练习50题(基于MySQL)后25题
    SQL练习50题(基于MySQL)前25题
    轮播2-css
    轮播1-animate-匀速
  • 原文地址:https://www.cnblogs.com/wadmwz/p/9321373.html
Copyright © 2011-2022 走看看