> 文章列表 > 参数有效性检测的隐患

参数有效性检测的隐患

参数有效性检测的隐患

在平时开发中,相信大家都见过大量的这样的代码:

void doXXX(String s){if(s == null){return;}//do something...
}

或者是另一种形式:

void doXXX(String s){if(s != null){//do something...}
}

但是这种程序看上去是在为安全考虑,但是却包含了一些隐患。文本就分享一些我对这类隐患的一些思考。(本文以判空为示例,这种想法可以延伸到其他参数有效的判断上)

问题描述

上面两个示例中的过程定义都不包含返回值,过程的执行是为了副作用(side-effect),但是过程的定义使得调用存在两种情况:1. 参数合法,产生期望的副作用;2. 参数不合法,调用无效。

但是在调用方看来:

doXXX(str);
doYYY();

不管是那种情况,doXXX调用都会正常执行完,然后执行doYYY。也就是说调用方不知道这个doXXX调用是否产生了预期的副作用,如果这里doYYY的调用或者后续程序执行依赖doXXX的副作用,那么就会导致问题。

究其根源,还是在于过程内容和名称(或者说期望)不符导致:这里的doXXX表示这个过程干xxx事,但是过程的内容并不一定干这个事情。

优化方案

对于上述问题,有以下处理方法

方法一:修改过程名

因为过程的内容是尝试/可能干这个xxx事,所以可以改为:

void mayDoXXX(String s){if(s == null){return;}//do something...
}

void tryDoXXX(String s){if(s == null){return;}//do something...
}

方法二:添加返回值

因为外部不知道这个过程是否正常调用,所以可以加返回值来表示正常调用与否:

boolean doSomething(String s){if(s == null){return false;}//do something...
}

这样调用方就可以通过检查返回值来判断调用是否生效。

方法三:非法情况抛出异常

boolean返回值只能表示正常与否,如果像告诉调用方无法正常执行内容的原因,还是得靠异常机制:

void doSomething(String s){if(s == null){throw new IllegalArgumentException("s can not be null!");}//do something...
}