Java学习第十七天——异常机制

1 概述

异常是Java中提供的一种识别及响应错误情况的一致性机制。有效地异常处理能使程序更加健壮、易于调试。

异常发生的原因有很多,比如

  1. 用户输入了非法数据
  2. 要打开的文件不存在
  3. 网络通信时连接中断
  4. JVM内存溢出
  5. 这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。

 异常发生的原因很多,尤其是用户输入和要打开的资源不存在
 * 这些异常出错后,会导致程序生命周期终止执行,从错误代码开始,之后的代码都不会执行
 * java中有一个专门模拟异常的类,就是Throwable,所有异常都继承这个类

2 之前常见的异常

空指针

下标越界

栈内存溢出

类型转换异常

3 继承体系

 4 Error

 4.1 概述

系统内部错误,这类错误由系统进行处理,程序本身无需捕获处理。 

比如:OOM(内存溢出错误)、VirtualMachineError(虚拟机错误)、StackOverflowError(堆栈溢出错误)等,一般发生这种情况,JVM会选择终止程序。

4.2 示例

//堆栈溢出错误

public class TestError {

    public static void recursionMethod() {

        recursionMethod();// 无限递归下去

    }

    public static void main(String[] args) {

        recursionMethod();

    }

}

报错信息:

Exception in thread "main" java.lang.StackOverflowError

    at com.TestError.recursionMethod(TestError.java:5)

    at com.TestError.recursionMethod(TestError.java:5)

    at com.TestError.recursionMethod(TestError.java:5)

    at com.TestError.recursionMethod(TestError.java:5)

    at com.TestError.recursionMethod(TestError.java:5)

    at com.TestError.recursionMethod(TestError.java:5)

... ...

5 Exception

 5.1 概述

Exception是所有异常类的父类。分为非RuntimeException和RuntimeException 。

  1. 非RuntimeException 
    指程序编译时需要捕获或处理的异常,如IOException、自定义异常等。属于checked异常。
  2. RuntimeException 
    指程序编译时不需要捕获或处理的异常,如:NullPointerException等。属于unchecked异常。一般是由程序员粗心导致的。如空指针异常、数组越界、类型转换异常等。

 5.2 常用方法

 异常处理的两种方式
 *                 1 throws: 抛出异常,告诉调用处这里可能有什么问题
 *                     如果你把异常抛给了调用处,那么调用处要么也抛出去,要么解决
 *                 2 try...catch...: 解决异常                       

代码如下

          //打开资源文件
            try{
                FileInputStream fiStream=new FileInputStream("D:/xxx");
                System.out.println(123);
            //}catch(Exception e){
        }catch(FileNotFoundException e){
            //打印错误的追踪栈帧,比较常用,适合程序员排错
            //e.printStackTrace();
            //获取错误信息,适合响应给用户
            String msg=e.getMessage();
            System.out.println(msg);
        }
            System.out.println(456);

 5.3 try...catch...

    第一种

   语法:try{
 *                                   高风险代码;
 *                         }catch(异常类型 变量){
 *                                   解决方案;
 *                         }
        第二种

 语法:try{
 *          高风险代码;
 * }catch(异常类型 变量){
 *              处理方案;
 * }catch(异常类型 变量){
 *          处理方案;
 * }...

其中catch中异常类型不能有继承关系,如果有继承关系,需要从子类到父类

第三种

语法: try(开启资源){
 *              高风险代码;
 *  }catch(异常类型 变量){
 *              处理措施;
 *  }

 5.4 覆写

代码实现:class A{
    public void m1() throws IOException{
        
    }
}
class B extends A{
    @Override
    //方法覆写,不能比原方法拥有更宽泛的异常
    //抛出的异常类可以是父类方法中抛出的类,也可以是对应的子类,但不能是他的父类
    //父类抛出一个异常类A,那么子类要么还抛出A,要么抛出A的子类,要么不抛出异常,但是不能是A的父类
    public void m1() throws FileNotFoundException {
    }

 5.5 Throws

 throws抛出异常,但并不会处理异常,是一种提醒机制
 *   如果调用的方法抛出一个编译时的异常,那么就用try...catch处理掉,或者也抛出
 * throws是抛出异常并不会解决异常,一般用于类库端(被调用的这个类)
 * 而try...catch...是解决异常的,一般用于客户端(调用其他类的这个类,一般客户端都有main方法)

 代码实现:public static void main(String[] args) throws FileNotFoundException{
        m1();
    }
    public static void m1() throws FileNotFoundException{
        m2();
    }
    public static void m2() throws FileNotFoundException{
        m3();
    }
    public static void m3() throws FileNotFoundException{
        FileInputStream fis=new FileInputStream("xxx");
    }

抛异常,可以同时抛出多个,逗号隔开,没有先后顺序

代码: public static void main(String[] args) throws Exception,FileNotFoundException,IOException{
    }

 5.6 Finally

   5.6.1 使用

finally: 必须执行的语句块, 比如:打开的资源需要关闭
 *   1 finally不能单独出现,必须和try一起使用,或者和try...catch...一起使用
 *   2 finally语句块只有一种不执行情况,那就是关闭虚拟机  System.exit(0);

   5.6.2 注意

finally中的return优先级比较高,所以即使在代码中位置靠后,只要不出现虚拟机关闭的情况,就会优先执行,前面的return在编译的class文件中会被去掉

  5.6.3 应用场景

代码实现:    FileInputStream fis=null;
        try {
            //打开资源
            fis=new FileInputStream("xxx");
            //xxx操作
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally{
            //关闭资源
            try {
                //判断是否打开资源,如果打开就关闭
                if(fis!=null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

 5.7 Throw

异常源点

Throw new 异常类(错误信息);

参考自定义异常

 5.8 自定义异常类

 5.8.1 定义

 1 继承一个已有的异常类
 *       判断是运行时异常还是编译时异常,如果是运行时异常需要继承RuntimeException,否则就继承Exception即可
 *       一般情况下我们写的一定是编译时异常
 *  2 公共的无参构造
 *  3 公共的有参构造,传入字符串,并在构造方法中把该字符串传递给父类

  5.8.2 应用场景

public static void login(String username,String password) throws UserException{
        if (username.equals("admin")) {
            if (password.equals("root")) {
                //TODO 登陆成功
                //return "登陆成功";
            }else{
                //TODO密码不正确
                //return "密码不正确";
                throw new UserException("密码不正确");
            }
        }else {
            //TODO用户名不正确
            //return "用户名不正确";
            throw new UserException("用户名不正确");
        }
    }

Scanner scanner=new Scanner(System.in);
        System.out.println("请输入用户名和密码:");
        String username=scanner.next();
        String password = scanner.next();
        // System.out.println(username+":"+password);
        // String result=UserService.login(username,password);
        // if (result.equals("登陆成功")) {
        // System.out.println("欢迎回来");
        // }else {
        // System.out.println(result);
        // }
        try {
            UserService.login(username,password);
            System.out.println("登陆成功");
        } catch (UserException e) {
            //e.printStackTrace();
            System.out.println(e.getMessage());
        } 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值