作用

可以简洁的完成参数检验,在进行业务逻辑代码前进行前置判断。并且避免了冗长的if语句。guava将所有检验的API都放置于Preconditions类中。

API

Preconditions类大致分为6种提供参数检验的方法,每种方法都有三个重载方法。重载方法的参数意义是:

  • 仅有待校验的参数:抛出的异常中没有错误消息;
  • 有一个Object对象作为额外参数:抛出的异常使用Object.toString() 作为错误消息;
  • *有一个String对象作为额外参数,还有一个Object[]参数,这两个参数也是适用于异常错误消息的,处理的方式类似于String.format将Object的参数按顺序替换掉String中的占位符(如%s)
  • 方法声明(不包括额外参数) 描述 检查失败时抛出的异常
    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

实例

如:我们在做登录操作的方法中,在未用前置条件前,代码可能会如下:

 public User login(String userName,String password){
if(StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)){
throw new RuntimeException("用户名或密码不能为空");
}
User user = userService.queryUserByUserNameAndPassword(userName,password);
if(null == user){
throw new RuntimeException("用户名或密码错误");
}
//…………………………………………省略业务逻辑…………………………………………
}

当使用了Preconditions类后

public User login(String userName,String password){
Preconditions.checkArgument(!(StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)),"用户名或密码不能为空");
User user = userService.queryUserByUserNameAndPassword(userName,password);
Preconditions.checkNotNull(user,"用户名或密码错误");
//…………………………………………省略业务逻辑…………………………………………
}

思考

相信大家也发现了,Preconditions类与Assert断言类的思想基本是一致的,通过这个思想,我们也可以实现属于自己的断言类从而提升自己的开发效率。

假设一个场景,我们是基于接口开发工作的,接口通过JSON传递数据给前端。此时我们先定义一个JSON的结构。

public class ResponseEntity<T> implements Entity<T>,Serializable{

    private static final long serialVersionUID = 1L;

    //数据实体
private T data; //结果码
private Integer code; //错误描述
private String message; //…………
}

自定义一个异常类

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);
} }

和上面的例子一样,我们现在实现一个完成登录的接口。

@RequestMapping("/login")
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);
}

现在我们传用户名和密码,其中账号为空:

接下来传错误的用户名和密码

正确的账号密码,完成登录

探索guava(一)——前置条件Preconditions类的更多相关文章

  1. Google Guava学习笔记——基础工具类Preconditions类的使用

    Preconditions类是一组静态方法用来验证我们代码的状态.Preconditons类很重要,它能保证我们的代码按照我们期望的执行,如果不是我们期望的,我们会立即得到反馈是哪里出来问题,现在我们 ...

  2. Guava学习之Preconditions

    在编写程序的时候,很多时候都需要检查输入的参数是否符合我们的需要,比如人的年龄需要大于0,名字不能为空:如果不符合这两个要求,我们将认为这个对象是不合法的,这时候我们需要编写判断这些参数是否合法的函数 ...

  3. 探索Win32系统之窗口类(转载)

    Window Classes in Win32 摘要 本文主要介绍win32系统里窗口类的运做和使用机制,探索一些细节问题,使win32窗口类的信息更加明朗化. 在本文中,"类", ...

  4. 《探索未知种族之osg类生物》目录

    精力有限,博客园不在更新<探索未知种族之osg类生物>.在这里列出所有文章目录(持续更新)有兴趣的同学可以看看. 探索未知种族之osg类生物[目录] 前序 探索未知种族之osg类生物--- ...

  5. 探索未知种族之osg类生物---状态树与渲染树以及节点树之间的关系

    节点树 首先我们来看一个场景构建的实例,并通过它来了解一下“状态节点”StateGraph 和“渲染叶”RenderLeaf 所构成的状态树,“渲染台”RenderStage 和“渲染元”Render ...

  6. [转][osg]探索未知种族之osg类生物【目录】

    作者:3wwang 原文链接:http://www.3wwang.cn/html/article_58.html 前序 探索未知种族之osg类生物---起源 ViewBase::frame函数中的Vi ...

  7. Guava的异常工具类--Throwables

    Guava为我们提供了一个非常方便并且实用的异常处理工具类:Throwables类. 这个类的API可以参见:http://docs.guava-libraries.googlecode.com/gi ...

  8. 探索未知种族之osg类生物---渲染遍历之裁剪二

    前言 上一节我们大致上过了一遍sceneView::cull()函数,通过研究,我们发现上图中的这一部分的代码才是整个cull过程的核心部分.所以今天我们来仔细的研究一下这一部分. sceneView ...

  9. 探索未知种族之osg类生物---渲染遍历之裁剪一

    前言 上面我们用了四节课的内容,讲解了一些osg概念性的内部原理.希望大家可以再看今天的讲解之前先再仔细的研究一下前四节的内容.这样你就会对整个osg的渲染过程有一个更加清晰的认知,有助于理解下面两个 ...

随机推荐

  1. 【夯实PHP基础】微信小程序开发 2017.02.06

    本文地址 分享提纲 1. 概述 2. 简易教程 1. 概述 1)[小程序是什么] 微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验. 2)[快速体验 ...

  2. Activity与view

    Activity的作用:一个Activity相当于一个容器,用于存放各种控件的容器,也可以理解为是与用户交互的接口 创建Activity的要点:  1.一个Activity就是一个类,并且这个类要继承 ...

  3. 详解PHP操作Memcache缓存技术提高响应速度的方法

    本文转载http://blog.csdn.net/zhihua_w  不错的博客,仅供本人学习之用 一般来说,如果并发量不大的情况,使不使用缓存技术并没有什么影响,但如果高并发的情况,使用缓存技术就显 ...

  4. [转]QDir类及其用法总结

    直接给出原文链接:QDir类及其用法总结

  5. Objective-C 基于Aspects

    JavaScriptCore没有禁,因为各种小程序都在用 网络下载文件没有禁

  6. 【Codeforces 111C】Petya and Spiders

    Codeforces 111 C 题意:给\(n\times m\)的网格,每个点上有一个蜘蛛,每个蜘蛛可以向上.下.左.右走一步或者不动,问最多能存在多少没有蜘蛛的点. 思路1: 首先因为\(n\) ...

  7. Zephyr的Time、Timer、sleep

    正如Linux下一样,关于时间的系统函数可以分为三类:时间值.睡眠一段时间以及延迟执行. 在Zephyr上对应是什么样子呢?带着这个疑问,去了解一下这些函数. 以及他们与suspend之间的关系? 是 ...

  8. c# WPF 设置窗口一直在其中窗口后面/底层窗口

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  9. [您有新的未分配科技点][BZOJ3545&BZOJ3551]克鲁斯卡尔重构树

    这次我们来搞一个很新奇的知识点:克鲁斯卡尔重构树.它也是一种图,是克鲁斯卡尔算法求最小生成树的升级版首先看下面一个问题:BZOJ3545 Peaks. 在Bytemountains有N座山峰,每座山峰 ...

  10. [spark][python]Spark map 处理

    map 就是对一个RDD的各个元素都施加处理,得到一个新的RDD 的过程 [training@localhost ~]$ cat names.txtYear,First Name,County,Sex ...