java异常处理机制

2018-03-09  本文已影响0人  luoqiang108

java异常捕获机制

throw关键字:用于主动抛出异常

使用环境:
我们常在方法中主动抛出异常。但不是什么情况下我们都应该抛出异常。原则上,自身决定不了的应该抛出。
方法中什么时候该自己处理异常什么时候该抛出?
方法通常有参数,调用者在调用我们的方法帮助解决问题是通常会传入参数,若我们方法的逻辑是因为参数的错误而引发的异常应该抛出,若是我们自身的原因应该自己处理。

throws关键字

声明方法的时候,我们可以同时声明可能抛出的异常种类,通知调用者强制捕获。
就是所谓的“丑话说前面”。
注意区分throw和throws关键字。笔试常问。
throw是抛出异常时使用的,throws是用于方法声明时定义可能抛出的异常。

java中抛出异常运行机制:

java虚拟机在运行程序时,一旦在某行代码运行时出现错误,jvm会创建这个错误的实例,并抛出。这时jvm会检查出错代码所在的方法是否有try捕获,若有,则检查catch块是否有可以处理该异常的能力。若没有,则将该异常抛给该方法的调用者。以此类推,直到抛至main方法外仍没有解决。那么jvm会终止该程序。

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * java异常处理机制
 * 我们程序中可以捕获的是Exception的子类异常
 * 而java中的异常有两大类
 * Exception:程序级别的异常,我们可控
 * Error:系统级别的异常,我们不可控
 *
 * 所以我们关心的是Exception的相关子类!
 *
 * 异常处理语句
 * try{
 *     可能发生异常的代码片段
 * }catch(Exception e){//列举代码中可能出现的异常类型
 *     当出现了列举的异常类型后,在这里处理
 * }
 */
public class ExceptionTest {
    public static void main(String[] args) {
        try {
            String info = "hello";
            //这里会引发空指针异常!
            System.out.println(info.length());
            System.out.println(info.charAt(9));
        }catch (NullPointerException e){
            System.out.println("这里字符串是空的!");//这里字符串是空的
        }catch (StringIndexOutOfBoundsException e){
            System.out.println("字符串没有那么长!");//字符串没有那么长!
        }catch (Exception e){
            /*良好的习惯,在异常捕获机制的最后书写catch(Exception e)
            * 捕获未知的错误(或不需要针对处理的错误)。*/
        }
        try {
            //String result = getGirlFirend("女神");
            //System.out.println("我追到了女神么?"+result);
            getGirlFirend(null);
        }catch (Exception e){
            //我们应该在这里捕获异常并处理。
            System.out.println("没追到。。。");
        }
        try {
            StringToDate("2018-03-09");
            //catch中必须包含有效的捕获stringToDate方法throws的异常
        } catch (ParseException e) {
            //输出这次错误的栈信息,可以直观的查看方法调用过程和出错的根源。
            e.printStackTrace();
        }
        /**
         * try-catch中finally块
         *
         * finally块定义在catch块的最后。只能出现一次。(0-1次)
         *
         * 无论程序是否出错都会执行的块!
         * 无条件执行,前面有return都还会执行!
         *
         * 注意final和finally的区别。
         */
        try {
            String info = null;
            System.out.println(info.charAt(9));
        }catch(NullPointerException e){
            e.printStackTrace();
        }catch (StringIndexOutOfBoundsException e){
            e.printStackTrace();
        }finally {
            //里面的语句无条件执行
            System.out.println("finally!!!");
        }
        System.out.println("程序结束了!");//程序结束了!
    }
    /**
     * throw关键字,可以主动抛出一个异常
     *
     * 应用环境:当我我们的方法出现错误时,这个错误我们不应该去解决,而是
     * 通知调用方法方去解决,会将这个错误告知外界,而告知外界
     * 的方式就是throw异常(抛出异常)
     */
    /**
     * 介绍女朋友
     * @param name 女朋友名字
     * @return 是否同意
     */
    public static String getGirlFirend(String name) {
        try {
            if ("春哥".equals(name)) {
                return "行";
            } else if ("曾哥".equals(name)) {
                return "行";
            } else if ("我女朋友".equals(name)) {
                return "不行";
            } else {
            /*当出现了错误(可能是业务逻辑上的,不一定是真实异常)
            * 我们可以主动向外界抛出一个异常!*/
                throw new RuntimeException("人家不干!");
            }
        }catch(NullPointerException e){
            throw e;//出错了不解决,抛给调用者解决。
        }
    }
    /**
     * throws关键字
     * 声明抛出异常的种类
     * 作用是通知调用者必须捕获异常
     */
    public static Date StringToDate(String str) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        /**
         * SimpleDateFormat的parse方法在声明的时候就使用了throws
         * 强制我们调用parse方法时必须捕获ParseException
         * 我们的做法是添加try-catch捕获该异常,或者在我们的方法
         * 声明也追加这种异常的抛出。
         */
        Date date = format.parse(str);
        return date;
    }

    /**
     * 抛出异常规范
     * throws的位置
     * 方法声明时参数列表的后面,方法体前半个大括号前面
     */
    public static void ruleTest(String str) throws ParseException {
        if (str==null){
            /**
             * 我们在方法中主动抛出异常,应该在方法声明时声明该异常的抛出
             */
            /**
             * NullPointerException是非检查异常(RuntimeExcption的子类)
             * 所有我们抛出该类异常实例时,方法声明处无需添加throws来
             * 列举该类异常的抛出。编译器在编译类时也忽略对这类异常
             * 抛出的检查(编译时不看他是不是在throws中被列举)。
             */
            throw new NullPointerException("有错误");
        }
        /*抛出非RuntimeExecption异常,该类异常称为检查异常
            * 编译器在编译该类时若发现方法中抛出了此类异常,
            * 那么一定会检查方法声明时是否含有throws该类异常的声明或对该异常进行try-catch异常捕获处理,
            * 若没有就判断为语法错误,编译不通过!
            */
        throw new ParseException("",0);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读