Java中Assert的生产环境参数校验中的应用


      Tony Hoare爵士有这样一个观点:"在测试时使用断言,而在产品发布时将断言关闭的程序员,就像是在岸上操练时穿着救生衣,而下海时将救生衣脱掉的水手。" 在java生产系统中,很少看到断言的存在,即使在用Junit测试,多数情况下也是System.out.println来获取结果,断言被束之高阁。存在即合理,jdk(1.4以后的版本)既然把assert作为他的关键字,肯定是系统应用中有相关的场景。

      java中的assert的语法:assert booleanvalue : error info。如果是返回false,则抛出java.lang.AssertionError,这个类继承了Error类(Error 是 Throwable 的子类,用于指示合理的应用程序不应该试图捕获的严重问题),所以系统抛出这类异常的时候,你可以不处理(这不代表你不能catch)。生产系统的多数异常都是需要处理并返回给用户,所以我们可以在系统设计的核心业务调用的位置catch AssertionError错误。

public void assertor(){
        int x =1;
        assert x==1?true:false;
        System.out.println("print yes");
        assert x==2?true:false : "有错误!";
        System.out.println("no print");
    }

       在eclipse执行这段代码,可以正常的执行完毕,并没有发现问题。这是因为eclipse默认是关闭断言的,通过添加参数 -ea 来打开断言,就发现有以下错误:
java.lang.AssertionError: 有错误!
       在代码中添加捕获异常的代码,然后可以做相关的处理。

public void assertor(){
        int x =1;
        assert x==1?true:false;
        System.out.println("print yes");
        try {
            assert x==2?true:false : "有错误!";
        } catch (AssertionError e) {
            System.out.println("has error");
        }
        System.out.println("no print");
    }

      在web service系统API中,请求过程中会有很多的参数校验,多数参数需要判断参数是否为空,程序中会有这样的代码:

if(StringUtils.isBlank("name")){
    //doing someting
}
if(StringUtils.isBlank("age")){
    //doing someting
}

      或者是重构一把,把参数放入map中,统一的去遍历map来解决这个问题。

Map<String,String> map = new HashMap<String, String>();
map.put("name",name);
//通过map来遍历处理抛出错误来校验。
public void VolicateNull(Map<String,String> map){
        for(Entry<String,String> entry:map.entrySet()){
            if(StringUtils.isBlank(entry.getValue())){
                throw new NullPointerException(entry.getKey());
            }
        }
}

      在我们new 对象的时候创建了系统资源,虽然jdk可以自动回收,但是也造成了相关的系统浪费,因为assert可以帮你完成相关操作的。我们可以在系统中这样:


assert StringUtils.isBlank("name") : "some message";
assert StringUtils.isBlank("age") : "some message";


而后捕获错误,做出相关的处理。

      也许你觉得JDK中的异常用的不爽,这些都是Error的东东,看着觉得头痛,那你可以常识用Sprint中的org.springframework.util.Assert类来做相关的处理,这个类抛出IllegalArgumentException异常,做参数的校验再好也不过了。里面的方法很全,可以看源码了解,例如为空的判断。

public static void isNull(Object object, String message) {
        if (object != null) {
            throw new IllegalArgumentException(message);
        }
}

相关内容