俗话说丑话讲在前面,在作某些事情的时候是须要作一些前置条件的。假如须要修改一条数据的话,当参数传进来,咱们要先查询这条数据是否存在。这时候就须要一个if了,若是参数还须要校验是否符合要求,就须要更多的if了,这无疑是让代码变得很难看。基于这一点,guava提供在 Preconditions 类。前端
前置条件:让方法调用的前置条件判断更简单。java
Guava 在 Preconditions 类中提供了若干前置条件判断的实用方法,强烈建议在 Eclipse 中静态导入这些方法。每一个方法都有三个变种:express
有点相似 printf,但考虑 GWT 的兼容性和效率,只支持%s 指示符。数组
checkArgument(i >= 0, "Argument was %s but expected nonnegative", i); checkArgument(i < j, "Expected i < j, but %s > %s", i, j);
Preconditions是被final修饰的,不可被继承less
Preconditions是能够直接使用的。 例如:单元测试
Preconditions.checkArgument(false);
方法太多,这里介绍无参的,其他的参考上述的三个变种。 | 方法名 | 描述 | 异常 | | ------------ | ------------ | ------------ | | checkArgument(boolean) | 检查boolean是否为true,用来检查传递给方法的参数。 | IllegalArgumentException | | checkNotNull(T) | 检查value是否为null,该方法直接返回value,所以能够内嵌使用checkNotNull。。 | NullPointerException | | checkState(boolean) | 用来检查对象的某些状态。 | IllegalStateException | | checkElementIndex(int index, int size) | 检查index做为索引值对某个列表、字符串或数组是否有效。index>=0 && index<size * | IndexOutOfBoundsException | | checkPositionIndex(int index, int size) | 检查index做为位置值对某个列表、字符串或数组是否有效。index>=0 && index<=size * | IndexOutOfBoundsException | | checkPositionIndexes(int start, int end, int size) | 检查[start, end]表示的位置范围对某个列表、字符串或数组是否有效* | IndexOutOfBoundsException |测试
Preconditions.checkArgument(!(StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)),"用户名或密码不能为空");
Preconditions.checkArgument(!(Preconditions.checkNotNull(username).isEmpty() || Preconditions.checkNotNull(password).isEmpty()),"用户名或密码不能为空");
Preconditions.checkArgument(false);Preconditions.checkArgument(false,"this is a test!"); //this is a test! Preconditions.checkArgument(false,"%s is a %s","hjh","pig"); //hjh is a pig Preconditions.checkElementIndex(20, 10); //java.lang.IndexOutOfBoundsException: index (20) must be less than size (10) Preconditions.checkPositionIndex(20, 10, "desc !!!!"); //java.lang.IndexOutOfBoundsException: desc !!!! (20) must not be greater than size (10) Preconditions.checkPositionIndex(20, 10); //java.lang.IndexOutOfBoundsException: index (20) must not be greater than size (10) Preconditions.checkState(false); // java.lang.IllegalStateException Preconditions.checkNotNull(1);//1 Preconditions.checkNotNull(null,"is null"); //java.lang.NullPointerException: is null Preconditions.checkNotNull(null, "%s is null !", "object"); //java.lang.NullPointerException: object is null !
Preconditions相似咱们写junit单元测试,与Assert断言类的思想也基本是一致的,经过这个思想,咱们也能够实现属于本身的断言类从而提高本身的开发效率。this
假设一个场景,咱们是基于接口开发工做的,接口经过JSON传递数据给前端。此时咱们先定义一个JSON的结构。code
public class ResponseEntity<T> implements Entity<T>,Serializable{ private static final long serialVersionUID = 1L; //数据实体 private T data; //结果码 private Integer code; //错误描述 private String message; //………… }
自定义一个异常类。orm
public class GlobException extends RuntimeException{ private static final long serialVersionUID = 1L; private String message; private Integer code; }
定义本身的前置条件类(断言类)。
/** * 断言类 * @author cjl */ public abstract class Assert { /** * 断言对象不为空,若对象为空则报异常 * @param obj 待校验对象 * @param message 异常信息 */ public static void notNull(Object obj,String message){ if(obj == null) throw new GlobException(message); } /** * 断言对象不为空,若对象为空则报异常 * @param obj 待校验对象 */ public static void notNull(Object obj){ Assert.notNull(obj, "The Object can't null"); } /** * 断言数字不能为零,若数字为零则报异常 * @param num 待校验数字 * @param message 异常信息 */ public static void notZero(Integer num,String message){ Assert.notNull(num); if(num.intValue() == 0) throw new GlobException(message); } /** * 断言数字不能为零,若数字为零则报异常 * @param num 待校验数字 */ public static void notZero(Integer num){ Assert.notZero(num,"The number can't equals zero"); } /** * 断言字符串不能为空,若字符串为空则报异常 * @param string 待校验字符串 * @param message 异常信息 */ public static void notEmpty(String string,String message){ if(StringUtils.isEmpty(string)) throw new GlobException(message); } /** * 断言字符串不能为空,若字符串为空则报异常 * @param string 待校验字符串 */ public static void notEmpty(String string){ Assert.notEmpty(string,"The string can't empty"); } /** * 断言该布尔值为true,若为false则抛异常 * @param expression 待校验布尔值 * @param message 异常信息 */ public static void isTrue(boolean expression,String message){ if(!expression) throw new GlobException(message); } /** * 断言该布尔值为true,若为false则抛异常 * @param expression 待校验布尔值 */ public static void isTrue(boolean expression){ Assert.isTrue(expression,"The expression not true"); } }
这时候在定义一个全局异常处理类,这里使用的是Spring Mvc的@ControllerAdvice注解。
** * 全局异常处理 * @author cjl */ @ControllerAdvice public class ExceptionHandlers { @SuppressWarnings("rawtypes") @ResponseBody @ExceptionHandler(GlobException.class) public ResponseEntity<?> exceptionHandler(GlobException exception){ outException(exception); return new ResponseEntity(exception); } /** * 异常输出 * @param exception */ private void outException(GlobException exception) { String content = String.format("****************系统发生异常(%s)************************", exception.getMessage()); System.out.println(content); } }
如今实现一个完成登陆的接口。
public ResponseEntity<?> login(String userName,String password){ Assert.isTrue(!(StringUtils.isEmpty(userName)||StringUtils.isEmpty(password)),"用户名或密码不能为空"); User user = userService.queryByUserNameAndPassword(userName, password); Assert.notNull(user,"用户名或密码错误"); return ResponseEntity.success(user); }