首页 国际新闻正文

来,guava探求系列之高雅校验数据,星美国际影城

典雅校验数据-前置条件

前语

依据防护式编程的要求, 在日常的开发中, 总少不了对函数的各种入参做校验, 以便确保函数能依照预期的流程履行下去. 比方各种费率的值就没可能是负数, 假如费率呈现负数, 所以数据有问题, 咱们需求做的工作便是把这些有问题的数据挑出来. 自己手写这些校验函数不免过于繁琐, 所幸的是咱们需求的函数已经有现成的:

Guava 供给了一系列的静态办法用于校验函数和类的结构器来,guava根究系列之典雅校验数据,星美世界影城是否契合预期, 并称其为前置条件(p人与牛reconditions). 假如前置条件校验失利, 王希克就会抛出一个指定的反常.

前置函数特征

现在的前置校验办法有如下特征:

须需求, 下面比方中的checkArgument函数能够替换成任何一个前置条件校验函数

这些前置办法一般承受一个布尔表达式作为入参,并判别表达是否为true, 格局如:

Preconditions.checkArgument(a>1)

// 假如表达式为false, 抛出IllegalArgumentException

除了用于判别的布尔表达式之外, 前置办法能够承受一个额定的Object作为入参, 在抛出反常的时分, 把Object.toString()作为反常信息, 如:

public enum ErrorDetail {

SC_NOT_FOUND("404", "Resource could not be fount");

// 省掉部分内容

@Override

public String toString() {

return "ErrorDetail{" + "code='" + code + '\'' + ", description='" + descripti来,guava根究系列之典雅校验数据,星美世界影城on + '\'' + '}';

}

}

@Test

public void testCheckArgument() {

Preconditions.checkArgument(1 > 2, ErrorDetail.SC_NOT_FOUND);

}

// 成果如下:

// java.lang.IllegalArgumentException: ErrorDetail{code='404', description='Resource c失独集体最新音讯ould not be fount'}

Guava的前置表达式还支撑相似printf函数那样的格局化输出过错信息, 只不过出于兼容性和功用的考虑, 只支撑运用%s指示符格局化字符串, 不支撑其他类型. 如:

int i=-1;

checkArgument(i >= 0, "Argument was %s but expected nonnegative", i);

// 成果如下:

// java.lang.IllegalArgumentException: Argument was -1 but expect申德勒码头餐厅ed nonnegative

前置条件函数介绍

须留意的是, 下面介绍的checkArgument, checkArgument, checkState函数都有三个对应的重载函数,别离对应前文所述的三种特征, 下文不会三种函数都介绍, 只介绍规范格局的前置条件函数. 以checkArgument函数为例, 三个重载函数别离是(疏忽函数体):

public static void checkArgument(boolean expression);

public static void checkArgument(boolean expression, @Nullable Object errorMessage);

public static void checkArgument(boolean expression,@Nullable String errorMessageTemplate,@Nullable Object... errorMessageArgs)

checkA来,guava根究系列之典雅校验数据,星美世界影城rgument

函数的签伊恩日记名如下:

public static void checkArgument(boolean expression);

入参是一个布尔表达式, 函数校验这个表达式是否为true, 假如为false, 抛出IllegalArgumentException. 比方如下:

@Test

public void testCheckArgument() {

Preconditions.checkArgument(1 > 2);

}

checkNotNull

这是个泛型函数, 函数签名如下:

public static T checkNotNull(T reference);

入参是个恣意类型的目标, 函数校验这个目标是否为null, 假如为空, 抛出NullPointerException, 不然直接回来该目标, 所以checkNotNull的用法就比较风趣, 能够在调用setter办法前作前置校验. 比方如下:

PreconditionTest caller = n沃金汇ew PreconditionTest();

caller.setErrorDetail(Preconditions.来,guava根究系列之典雅校验数据,星美世界影城checkNotNull(ErrorDetail.SC_INTERNAL_SERVER_ERROR));

checkState

函数签名如下:

public static void checkState(boolean expression);

看着这个函数, 我个人感觉很古怪: 这个函数和checkNotNull函数功用十分相似, 完成也根本相同, 都是判别表达式是否为true, 仅仅抛出的反常不相同罢了, 是否有必要开发这个函数. 两个函数的完成如下:

public static void checkArgument(boolean expression) {

if (!expression) {

throw new IllegalArgumentException();

}

}

public static void checkState(boolean expression) {

if (!expression) {

throw new IllegalStateException();

}

}

此外, 由于这两个函数适当相似, 就不展现相应比方了.

checkElementIndex

函数签名如下:

public static int checkElementIndex(int index, int size);

这个函数用于判别指定数组, 列表, 字符串的下标是否越界, index是下标, size是数组, 列表或字符串的长度, 下标的有用规模是[0老男同志,数组长度) 即 0<=index<0 或许 index>=size), 调教丈夫那么抛出IndexOutOfBoundsException反常, 不然回来数组的下标, 也便是index. 比方如下:

Preconditions.checkElementIndex("test".length(), "test".length());

// 运转成果:

// 抛出反常: java.lang.IndexOutOfBoundsException: index (4) must be less than size (4)

Assert.assertEquals(3, Preconditions.checkElementIndex("test".length() - 1, "test".length()));

// 运转成果:

// 经过

checkPositionIndex

函数的签名如下:

public 露胸相片static int che兄妹一家亲ckPositionIndex(int index, int size);

这个函数和checkElementIndex十分相似, 连Guava wiki的阐明也根本共同(只要一个单词不同), 除了一点, checkElementIndex函数的下标有用规模是[0, 数组长度), 而checkPositionIndex函数的下标有有用规模是[0, 数组长度], 即0<=index<=size. 比方如下:

Preconditions.checkPositionIndex("test来,guava根究系列之典雅校验数据,星美世界影城".length() + 1, "test".length());

// 运转成果:

// 抛出反常: java.lang.IndexOutOfBoundsException: index (5) must be less than size (4)

Assert.assertEquals(4, Preconditions.checkPositionIndex("test".length(), "test".length()));

// 运转成果:

// 经过

checkPositionIndexes

函数的签名如下:

public static void checkPositionIndexes(int start, int end记李将军回来, int size);

这个函数是用于判别[start,end]这个规模是否是个有用规模, 即[start, end] 是否在[0, size] 规模内(假如[start, en综穿之佳人如斯d] 和[0, size]相同, 也以为在规模内),豆芽姐视频 假如不在, 则抛出IndexOutOfBoundsException反常. 比方如下:

Preconditions.checkPositionIndexes(1, 3, 2);

// 运转成果:

// 抛出反常: java.lang.IndexOutOfBoundsException: end index (3) must not be greater than size (2)

Preconditions.checkPositionIndexes(0, 2, 2);

// 运转成果:

// 校验经过

前置条件在实践项目的运用

前置条件在查验条件不成交的时分抛的反常类型虽然是入情入理(比方, checkArgument函数抛出IllegalArgumentException), 可是关于事务体系来说, 你抛出个IllegalArgumentException或许NullPointerExceptio郭柏雄n, 接口调用方关于这个反常摸不着头脑, 虽然仅仅正常的数据问题, 仍是很简单觉得接口供给方服务出了问题, 乃至还会被质疑技能不过硬. 咱们又不是底层组件, 抛个NPE, 着实是不成体统. 根据各种有的没的的原因, 咱们的事务体系在运用前置条件的时分进行了封装, 将前置条件抛出的反常进行了转化, 换成正常的事务异吉冈昌仁常, 供给完好的反常信息, 代码如下:

// 封装代码:

public final class AssertUtils {

/**

* 查看条件表达式是否为真

*

* @pa锦衣当朝ram expression 条件表达式

* @param errDetailEnum 过错码

* @param msgTemplate 过错音讯模板

* @param vars 占位符对应变量

* @throws BkmpException 条件表达式成果为假

*/

public static void checkArgument(boolean expression, ErrDetailEnum errDetailEnum, String msgTemplate,

Object... vars) {

try {

Preconditions.checkArgument(expression);

} catch (Illega甲申风云lArgumentException e) {

throw new BkmpException(errDetailEnum, msgTemplate, vars);

}

}

/**

* 查看条件表达式是否为假

*

* @param expression 条件表达式

* @param errDetailEnum 过错码

* @param msgTemplate 过错音讯模板

* @param vars 占位符对来,guava根究系列之典雅校验数据,星美世界影城应变量

* @throws BkmpException 条件表达式成果为假

*/

public st来,guava根究系列之典雅校验数据,星美世界影城ati天鹅劫c void checkArgumentNotTrue(boolean expression, ErrDetailEnum errDetailEnum, String msgTemplate,

Object... vars) {

try {

Preconditions.checkArgument(!expression);

} catch (IllegalArgumentException e) {

throw new BkmpException(errDetailEnum, msgTemplate, vars);

}

}

}

// 省掉其他部分的封装

// 调用比方:

AssertUtils.checkArgument(merchantEntity.exist(), ErrDetailEnum.DATA_NOT_EXIT, "商户不存在");

Guava Precondition vs Apache Common Validate

自古文无榜首, 武无第二, 文人之间的口水战总是少不了的. 没想到这不是国人的专利, 本来国外也有文人相轻的习尚: Guava wiki 在介绍完preconditions之后, 还踩了一波竞品Apache Common Validate, 以为Guava的preconditions 比Apache Common 愈加明晰明晰, 也愈加漂亮, 我个人对Apache Common Validate 了解不深, 也欠好随意置喙. 除了踩竞品之外, Guava wiki 还提了两点最佳实践(best practice):

运用前置条件校验的时分, 引荐每个校验条件独自一行, 这样即更了然, 出问题也更便利调试.

运用前置条件校验的时分, 尽量供给有用的过错信息, 这样能够更快地定位问题.

参考资料

PreconditionsExplained

总结

代码大全一书有一章是关于防护式编程的, 用于进步程序的健壮性, 首要思维是子程序应该不因传入过错数据而被损坏,要维护程序免遭不合法输入数据的损坏. 而Guava的preconditions 便是完成防护式编程的有力东西呢. oh ye陈林菠ah!

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。