Java中的异常处理

简介

定义:异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。

异常发生的原因有很多,通常包含以下几大类:

  • 用户输入了非法数据。
  • 要打开的文件不存在。
  • 网络通信时连接中断,或者JVM内存溢出。

这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。

异常分类及类结构图

一般将异常归为三类:

  • 检查性异常:这种异常,一般是程序员无法预知的,例如打开文件。目前很多编辑器都有提示检查性异常的功能,如下:
    在这里插入图片描述
    这类异常,在编译时不能被忽略,执行main方法时会提示如下错误:
    在这里插入图片描述
    这时需要我们手动加上相应的捕获或者声明:
    在这里插入图片描述

  • 运行时异常:这类异常比较常见,编译的时候检查不出来,但可以被我们所避免,如NPE。

  • 错误:错误不是异常,程序员一般是处理不了的,编译的时候也检查不出来。
    异常类的结构图大致如下:
    在这里插入图片描述

异常处理的基本语法

在编写代码的时候,对于检查性异常,一般有两种处理方式,一种是用try…catch…finally语句块处理,一种是在方法后面用throws声明,让调用者去处理。
try…catch…finally语句块

	try {
            //这里放置的是业务代码,
            // 也就是包含throw new XXException()的代码
        } catch (Exception e/*这里的Exception是父类,可以用具体的XXException代替,前提是确认会抛XXException*/) {
            //这里可以对异常进行处理,可以返回一个什么数据,
            // 也可以打印日志,也可以在这里再将异常抛出去
            //至少有一个catch
        } finally {
            //这里是可选的,无论异常是否发生、异常是否匹配被处理,finally块都会执行
            //finally里的return会覆盖catch里的return
            //finally主要做一些清理工作,比如shutdown,close
            //一些io流的close可以放在try()里面
        }

tips,一般而言,finally块最好不要乱用

  1. 不要在fianlly中使用return。
  2. 不要在finally中抛出异常。
  3. 减轻finally的任务,不要在finally中做一些其它的事情,finally块仅仅用来释放资源是最合适的。
  4. 将尽量将所有的return写在函数的最后面,而不是try … catch … finally中。

throws声明

public static void throwAnException() throws RuntimeException {
        throw new RuntimeException("exception");
    }

throw 和 throws的区别
throws是用来声明一个方法可能抛出的所有异常信息,throws是将异常声明但是不处理,而是将异常往上传,谁调用我就交给谁处理。而throw则是指抛出的一个具体的异常类型。

自定义异常

一般我们在写项目的时候,会使用自定义异常,而自定义异常,一般继承自RuntimeException

public class MyRuntimeException extends RuntimeException {

    private String errCode;

    public MyRuntimeException(String meg, String errCode) {
        super(meg);
        this.errCode = errCode;
    }
}

由于Throwable有个private String detailMessage;属性,我们可以调用它的getMessage()方法获取异常所携带的信息。而我们自己定义异常的时候,往往会去定义一个errCode,如500等;
自定义异常的使用,和jdk里的异常是一样的,但是我们可以进行包装;

public class MyExceptionBuilder {

    public static MyRuntimeException build(String msg, String code) {
        return new MyRuntimeException(msg, code);
    }

    public static MyRuntimeException build(ErrCodeEnum errCodeEnum) {
        return new MyRuntimeException(errCodeEnum.getMsg(), errCodeEnum.getCode());
    }
}

包装的作用是可以简化每次都要去主动new一个Exception,通过包装,简单得多了,可以直接如下:

throw MyExceptionBuilder.build("err", "500");

我们还可以自定义异常的枚举,如上面的ErrCodeEnum,将异常信息维护在枚举中。

todo
下一篇,会在这篇的基础上,讲解一下Web应用开发中异常的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值