1. 程式人生 > >Guava學習筆記:Preconditions優雅的檢驗引數

Guava學習筆記:Preconditions優雅的檢驗引數

在日常開發中,我們經常會對方法的輸入引數做一些資料格式上的驗證,以便保證方法能夠按照正常流程執行下去。對於可預知的一些資料上的錯誤,我們一定要做事前檢測和判斷,來避免程式流程出錯,而不是完全通過錯誤處理來保證流程正確執行,畢竟錯誤處理是比較消耗資源的方式。在平常情況下我們對引數的判斷都需要自己來逐個寫方法判斷,程式碼量不少並且複用性不高,如下所示:

    
import org.junit.Test;public class PreconditionsTest {        @Test    public void Preconditions() throws Exception {                 getPerson(
8,"peida");                getPerson(-9,"peida");                getPerson(8,"");                getPerson(8,null);    }    public static void getPerson(int age,String neme)throws Exception{        if(age>0&&neme!=null&&neme.isEmpty()!=true){            System.out.println("a person age:"+age+",neme:"+neme);        }
else{            System.out.println("引數輸入有誤!");        }    }}
   

說明:引數驗證,我們每次都要新增if語句來做判斷, 重複的工作會做好多次。getPerson方法只有2個引數,驗證規則也不是很複雜,如果引數過度,驗證規則複雜後,上面程式碼的可讀性都會很差的,複用性就更談不上了。

 

Guava類庫中提供了一個作引數檢查的工具類--Preconditions類, 該類可以大大地簡化我們程式碼中對於引數的預判斷和處理,讓我們對方法輸入引數的驗證實現起來更加簡單優雅,下面我們看看Preconditions類的使用例項:

    
import
org.junit.Test;import com.google.common.base.Preconditions;public class PreconditionsTest {        @Test    public void Preconditions() throws Exception {                 getPersonByPrecondition(8,"peida");                try {            getPersonByPrecondition(-9,"peida");        } catch (Exception e) {            System.out.println(e.getMessage());        }                try {            getPersonByPrecondition(8,"");        } catch (Exception e) {            System.out.println(e.getMessage());        }                try {            getPersonByPrecondition(8,null);        } catch (Exception e) {            System.out.println(e.getMessage());        }     }        public static void getPersonByPrecondition(int age,String neme)throws Exception{        Preconditions.checkNotNull(neme, "neme為null");        Preconditions.checkArgument(neme.length()>0, "neme為\'\'");        Preconditions.checkArgument(age>0, "age 必須大於0");        System.out.println("a person age:"+age+",neme:"+neme);    }}
   

執行結果:

    
a person age:8,neme:peidaage 必須大於0neme為''neme為null
   

Preconditions裡面的方法:

 

1 .checkArgument(boolean) : 功能描述:檢查boolean是否為真。 用作方法中檢查引數 失敗時丟擲的異常型別: IllegalArgumentException

 

2.checkNotNull(T):      功能描述:檢查value不為null, 直接返回value; 失敗時丟擲的異常型別:NullPointerException 3.checkState(boolean): 功能描述:檢查物件的一些狀態,不依賴方法引數。 例如, Iterator可以用來next是否在remove之前被呼叫。 失敗時丟擲的異常型別:IllegalStateException 4.checkElementIndex(int index, int size): 功能描述:檢查index是否為在一個長度為size的list, string或array合法的範圍。 index的範圍區間是[0, size)(包含0不包含size)。無需直接傳入list, string或array, 只需傳入大小。返回index。   失敗時丟擲的異常型別:IndexOutOfBoundsException

 

5.checkPositionIndex(int index, int size): 功能描述:檢查位置index是否為在一個長度為size的list, string或array合法的範圍。 index的範圍區間是[0, size)(包含0不包含size)。無需直接傳入list, string或array, 只需傳入大小。返回index。 失敗時丟擲的異常型別:IndexOutOfBoundsException

 

6.checkPositionIndexes(int start, int end, int size): 功能描述:檢查[start, end)是一個長度為size的list, string或array合法的範圍子集。伴隨著錯誤資訊。 失敗時丟擲的異常型別:IndexOutOfBoundsException

 

一個比較實用例項:

    
import java.util.ArrayList;import java.util.List;import org.junit.Test;import com.google.common.base.Preconditions;public class PreconditionsTest {        @Test    public void Preconditions() throws Exception {                 getPersonByPrecondition(8,"peida");                try {            getPersonByPrecondition(-9,"peida");        } catch (Exception e) {            System.out.println(e.getMessage());        }                try {            getPersonByPrecondition(8,"");        } catch (Exception e) {            System.out.println(e.getMessage());        }                try {            getPersonByPrecondition(8,null);        } catch (Exception e) {            System.out.println(e.getMessage());        }                List<Integer> intList=new ArrayList<Integer> ();        for(int i=0;i<10;i++){                        try {                checkState(intList,9);                intList.add(i);            } catch (Exception e) {                System.out.println(e.getMessage());            }        }                try {            checkPositionIndex(intList,3);            } catch (Exception e) {            System.out.println(e.getMessage());        }                try {            checkPositionIndex(intList,13);            } catch (Exception e) {            System.out.println(e.getMessage());        }                try {            checkPositionIndexes(intList,3,7);        } catch (Exception e) {            System.out.println(e.getMessage());        }                try {            checkPositionIndexes(intList,3,17);        } catch (Exception e) {            System.out.println(e.getMessage());        }                try {            checkPositionIndexes(intList,13,17);        } catch (Exception e) {            System.out.println(e.getMessage());        }                try {            checkElementIndex(intList,6);        } catch (Exception e) {            System.out.println(e.getMessage());        }                try {            checkElementIndex(intList,16);        } catch (Exception e) {            System.out.println(e.getMessage());        }    }        public static void getPersonByPrecondition(int age,String neme)throws Exception{        Preconditions.checkNotNull(neme, "neme為null");        Preconditions.checkArgument(neme.length()>0, "neme為\'\'");        Preconditions.checkArgument(age>0, "age 必須大於0");        System.out.println("a person age:"+age+",neme:"+neme);             }        public static void checkState(List<Integer> intList,int index)throws Exception{        //表示式為true不拋異常        Preconditions.checkState(intList.size()<index, " intList size 不能大於"+index);    }        public static void checkPositionIndex(List<Integer> intList,int index) throws Exception{        Preconditions.checkPositionIndex(index, intList.size(), "index "+index+" 不在 list中, List size為:"+intList.size());    }        public static void checkPositionIndexes(List<Integer> intList,int start,int end) throws Exception{        Preconditions.checkPositionIndexes(start, end, intList.size());    }        public static void checkElementIndex(List<Integer> intList,int index) throws Exception{        Preconditions.checkElementIndex(index, intList.size(),"index 為 "+index+" 不在 list中, List size為: "+intList.size());    }}
   

輸出結果:

    
a person age:8,neme:peidaage 必須大於0neme為''neme為null intList size 不能大於9index 13 不在 list中, List size為:9 (13) must not be greater than size (9)end index (17) must not be greater than size (9)start index (13) must not be greater than size (9)index 為 16 不在 list中, List size為: 9 (16) must be less than size (9)
     

Guava的preconditions有這樣幾個優點:

 

在靜態匯入後, 方法很明確無歧義, checkNotNull可以清楚地告訴你它是幹什麼的, 它會丟擲怎樣的異常. checkNotNull在驗證通過後直接返回, 可以這樣方便地寫程式碼: this.field = checkNotNull(field).      簡單而又強大的可變引數'printf'風格的自定義錯誤資訊.