GUAVA--基礎工具(Preconditions)

一、前置條件

俗話說醜話講在前面,在作某些事情的時候是須要作一些前置條件的。假如須要修改一條數據的話,當參數傳進來,咱們要先查詢這條數據是否存在。這時候就須要一個if了,若是參數還須要校驗是否符合要求,就須要更多的if了,這無疑是讓代碼變得很難看。基於這一點,guava提供在 Preconditions 類。前端

前置條件:讓方法調用的前置條件判斷更簡單。java

Guava 在 Preconditions 類中提供了若干前置條件判斷的實用方法,強烈建議在 Eclipse 中靜態導入這些方法。每一個方法都有三個變種:express

  • 沒有額外參數:拋出的異常中沒有錯誤消息;
  • 有一個 Object 對象做爲額外參數:拋出的異常使用 Object.toString() 做爲錯誤消息;
  • 有一個 String 對象做爲額外參數,而且有一組任意數量的附加 Object 對象:這個變種處理異常消息的方式

有點相似 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

Preconditions是被final修飾的,不可被繼承less

2.一、使用Preconditions

Preconditions是能夠直接使用的。 例如:單元測試

Preconditions.checkArgument(false);

2.二、方法

方法太多,這裏介紹無參的,其他的參考上述的三個變種。 | 方法名 | 描述 | 異常 | | ------------ | ------------ | ------------ | | 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 |測試

2.三、例子

2.3.一、校驗用戶名密碼
Preconditions.checkArgument(!(StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)),"用戶名或密碼不能爲空");
2.3.二、混用
Preconditions.checkArgument(!(Preconditions.checkNotNull(username).isEmpty() || Preconditions.checkNotNull(password).isEmpty()),"用戶名或密碼不能爲空");
2.3.三、更多例子
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);
}
相關文章
相關標籤/搜索