首页 > Java > 异常处理的一般方法

异常处理的一般方法

学习Java的应该都知道,异常处理是其一大特色,使用异常处理的最大优势就是:将问题处理代码和正常执行流程做了区分,使得程序的执行逻辑更加清晰,不再使错误处理代码和正常业务逻辑代码混在一起。Java不仅自己定义了各种各样的异常类来描述一些基本的错误现象,而且还提供了扩展机制,允许程序猿自定义异常类,应用于实际问题处理,Java的异常处理机制可以捕获对应的异常,并进行主动处理,那么既然Java的异常处理机制这么好用,有没有一般性的方法呢?

首先说明,(1). Java的异常分为:Error和Exception,Error类及其子类表示不是不可能恢复但很难处理的情况下的一种严重问题,例如内存溢出(大家可以想想Java是否存在内存溢出现象?),我们不可能指望程序能处理,所以本文所有的方法都是针对Exception。

(2). 异常处理就五个关键字:try、catch、finally、throw、throws,他们的用法也比较简单,本文不再赘述。

好了,下面开讲:

1. Exception分为两类:Exception和RuntimeException,其中Exception必须在系统中处理,而RuntimeException继承与Exception,表示一种设计或实现的问题,如果系统正常运行,此类异常不会出现,例如最常见的NullPointerException,所以一般不强制要求处理。

2. 像ClassNotFoundException这类异常,一般是jar包没有添加,在系统正常运行中肯定不会出现,所以无需抛出,可以直接try catch掉,但别忘了打log。

3. 像SQLException之类的,这类异常偶然也会出现,如:数据库服务没打开、没有网络、SQL语法有误等,但这类异常即使抛到Service层依然无法处理,抛到客户端客户也看不懂,还影响用户体验,所以也不要抛出,一般都是转化为RuntimeException,在转化之前打log。

4. 所以需要我们处理的异常只有ValidationException和BusinessException,这两类异常都是我们自定义的异常,其中ValidationException处理的是验证异常,而BusinessException处理的是业务逻辑异常,这两类异常都需要我们在系统中做出处理,下面会给出ValidationException、BusinessException和自定义转化为RuntimeException的参考方法。

5. Service层是负责业务逻辑处理的一层,所以所有的验证都要放在Service层,而Service层在进行验证和业务逻辑处理的时候,应该抛出这些所遇到的异常,并加入到ValidationException(如用户登录时用户名或密码为空等)或者BusinessException(如用户名或密码不正确等)异常中,然后在上层(servlet或者Action或者、controller)中进行捕获,捕获到之后放到Request中,带到前台进行处理。

6. 千万要记得出现异常一定要打log!!!尤其是当你try catch掉一个异常时。其中ValidationException、BusinessException日志级别为warning或info,其他的据具体情况而定,但MyRuntimeException 可以不打,大家可以想想为什么?(前面有答案)

7. 顺便说一下,关闭资源一定要放在finally里,因为finally的代码无论是否有异常都会被执行,确保打开的资源一定都会被关闭。

在这里顺便回答一些同学的问题:

(1)、我在前台已经做了验证,那么是否还需要在后台再做验证?

答:肯定要,原因①、前台验证一般都是用js来做,而js的解析是在客户端,如果有人禁用了浏览器的js,是不是你的验证就不起作用了。(关于如何禁用js,请自己用Google百度一下);

②、不排除有些黑客要黑你,所以他们可以通过一些工具,直接绕过前台,那么你懂得。

(2)、为什么要抽象Service层,为什么不把Service层的功能全放到servlet中来做,简单来说为什么要把验证放到Service层?

答:首先为什么抽象Service层,肯定是为了复用,这个是关于分成模型中要讲的,有机会我会在写一篇博文,专讲分层的一般方法,这里不多说,大家可以试想一下,目前移动端越来越火,而我们的servlet是和web相关,那么我们的Servlet能被App复用吗?如果我们把验证放到servlet中,那么如果在开发一套App,我们是不是所有的验证都要重写一篇?而放在Service层则没有这个问题。

(3)、Java是否存在内存溢出问题?

答:一般是不存在的,因为jvm有GC机制,会很好的管理内存,但有时候当我们短时间内,打开很多资源而没有关闭的时候,是可能会存在内存溢出问题的。


package cn.bridgeli.exceptionhandle.exception;

public class BusinessException extends Exception {

    private static final long serialVersionUID = 1L;

    private int code;

    public BusinessException(int code, String message) {

        super(message);

        this.code = code;

    }

    public int getCode() {

        return code;

    }

}

package cn.bridgeli.exceptionhandle.exception;

public class MyRuntimeException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    private int code;

    public MyRuntimeException(int code, String message) {

        super(message);

        this.code = code;

    }

    public int getCode() {

        return code;

    }

}

package cn.bridgeli.exceptionhandle.exception;

import java.util.HashMap;

import java.util.Map;

public class ValidationException extends Exception {

    private static final long serialVersionUID = 1L;

    private Map<String, String> errorFields = new HashMap<String, String>();

    public ValidationException() {

    }

    public void addErrorFiel(String name, String message) {

        errorFields.put(name, message);

    }

    public String getErrorField(String name) {

        if (errorFields.containsKey(errorFields)) {

            return errorFields.get(name);

        }

        return "";
    }
}

分享到:
作 者: BridgeLi,http://www.bridgeli.cn/
原文链接:https://www.bridgeli.cn/archives/15
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。
分类: Java 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.