相信Apache的大名各位一定不會陌生,Java領域中常用的Ant,Maven,Struts1~2等都是托管在Apache下的項目,而在使用Apache框架的時候,通常要添加框架的依賴包,包括apache-commons系列的依賴包,相信讀者對此也不會陌生,而apache-common是非常有用的工具包,包含了很多開源的工具,用于解決平時編程經常會遇到的問題,減少重復勞動
?
????? 一個優秀的類應該重寫toString,hashCode,equals,compareTo方法,我們來看一下apache如何帶我們簡化這些操作,以下示例支持兩種形式,一種是通過逐個參數添加從而精細控制那些參數參與比較和輸出,另一種是通過反射讓全部參數都參與比較和輸出
?
????? Builder系列
?
- //ToStringBuilder ??
- @Override ??
- public ?String?toString()?{??
- ???? return ? new ?ToStringBuilder( this ).append( this .getId())??
- ????????????.append( this .getUsername()).toString();??
- }??
- ??
- @Override ??
- public ?String?toString()?{??
- ???? return ?ToStringBuilder.reflectionToString( this );??
- }??
- //?以上輸出格式為??Test@1270b73[<null>,<null>] ??
- ??
- ??
- ??
- //?HashCodeBuilder ??
- @Override ??
- public ? int ?hashCode()?{??
- ???? return ?HashCodeBuilder.reflectionHashCode( this );??
- }??
- ??
- @Override ??
- public ? int ?hashCode()?{??
- ???? return ? new ?HashCodeBuilder( this ).append( this .getId())??
- ????????????.append( this .getUsername()).hashCode();??
- }??
- ??
- ??
- ??
- //?EqulasBuilder ??
- @Override ??
- public ? boolean ?equals(Object?obj)?{??
- ???? if ?( this ?==?obj)?{??
- ???????? return ? true ;??
- ????}??
- ???? if ?(obj.getClass()?==?Test. class )?{??
- ????????Test?test?=?(Test)?obj;??
- ???????? return ? new ?EqualsBuilder().append( this .getId(),?test.getId())??
- ????????????????.append( this .getUsername(),?test.getUsername()).isEquals();??
- ????}??
- ???? return ? false ;??
- }??
- @Override ??
- public ? boolean ?equals(Object?obj)?{??
- ???? return ?EqualsBuilder.reflectionEquals( this ,?obj);??
- }??
- ??
- ??
- //?CompareToBuilder ??
- @Override ??
- public ? int ?compareTo(Test?o)?{??
- ???? return ?CompareToBuilder.reflectionCompare( this ,?o);??
- }??
- ??
- @Override ??
- public ? int ?compareTo(Test?o)?{??
- ???? return ? new ?CompareToBuilder().append( this .getId(),?o.getId())??
- ????????????.append( this .getUsername(),?o.getUsername()).toComparison();??
- }??
- //ToStringBuilder ??
- @Override ??
- public ?String?toString()?{??
- ???? return ? new ?ToStringBuilder( this ).append( this .getId())??
- ????????????.append( this .getUsername()).toString();??
- }??
- ??
- @Override ??
- public ?String?toString()?{??
- ???? return ?ToStringBuilder.reflectionToString( this );??
- }??
- //?以上輸出格式為??Test@1270b73[<null>,<null>] ??
- ??
- ??
- ??
- //?HashCodeBuilder ??
- @Override ??
- public ? int ?hashCode()?{??
- ???? return ?HashCodeBuilder.reflectionHashCode( this );??
- }??
- ??
- @Override ??
- public ? int ?hashCode()?{??
- ???? return ? new ?HashCodeBuilder( this ).append( this .getId())??
- ????????????.append( this .getUsername()).hashCode();??
- }??
- ??
- ??
- ??
- //?EqulasBuilder ??
- @Override ??
- public ? boolean ?equals(Object?obj)?{??
- ???? if ?( this ?==?obj)?{??
- ???????? return ? true ;??
- ????}??
- ???? if ?(obj.getClass()?==?Test. class )?{??
- ????????Test?test?=?(Test)?obj;??
- ???????? return ? new ?EqualsBuilder().append( this .getId(),?test.getId())??
- ????????????????.append( this .getUsername(),?test.getUsername()).isEquals();??
- ????}??
- ???? return ? false ;??
- }??
- @Override ??
- public ? boolean ?equals(Object?obj)?{??
- ???? return ?EqualsBuilder.reflectionEquals( this ,?obj);??
- }??
- ??
- ??
- //?CompareToBuilder ??
- @Override ??
- public ? int ?compareTo(Test?o)?{??
- ???? return ?CompareToBuilder.reflectionCompare( this ,?o);??
- }??
- ??
- @Override ??
- public ? int ?compareTo(Test?o)?{??
- ???? return ? new ?CompareToBuilder().append( this .getId(),?o.getId())??
- ????????????.append( this .getUsername(),?o.getUsername()).toComparison();??
- }??
????? 使用commons能最大程度的簡化代碼,實現one-line編程,注意使用反射形式的時候,static和transient不會參與比較或輸出,要特別注意
?
????? 有些情況下,Arrays滿足不到你對數組的操作?不要緊,ArrayUtils幫你
?
????? ArrayUtils
?
- public ? class ?TestMain?{??
- ??
- ???? public ? static ? void ?main(String[]?args)?{??
- ???????? int []?nums1?=?{? 1 ,? 2 ,? 3 ,? 4 ,? 5 ,? 6 ?};??
- ???????? //?通過常量創建新數組 ??
- ???????? int []?nums2?=?ArrayUtils.EMPTY_INT_ARRAY;??
- ??
- ???????? //?比較兩個數組是否相等 ??
- ????????ArrayUtils.isEquals(nums1,?nums2);??
- ??
- ???????? //?輸出數組,第二參數為數組為空時代替輸出 ??
- ????????ArrayUtils.toString(nums1,? "array?is?null" );??
- ??
- ???????? //?克隆新數組,注意此拷貝為深拷貝 ??
- ???????? int []?nums3?=?ArrayUtils.clone(nums1);??
- ??
- ???????? //?截取數組 ??
- ????????ArrayUtils.subarray(nums1,? 1 ,? 2 );??
- ??
- ???????? //?判斷兩個數組長度是否相等 ??
- ????????ArrayUtils.isSameLength(nums1,?nums2);??
- ??
- ???????? //?判斷兩個數組類型是否相等,注意int和Integer比較時不相等 ??
- ????????ArrayUtils.isSameType(nums1,?nums2);??
- ??
- ???????? //?反轉數組 ??
- ????????ArrayUtils.reverse(nums1);??
- ??
- ???????? //?查找數組元素位置 ??
- ????????ArrayUtils.indexOf(nums1,? 5 );??
- ??
- ???????? //?查找數組元素最后出現位置 ??
- ????????ArrayUtils.lastIndexOf(nums1,? 4 );??
- ??
- ???????? //?查找元素是否存在數組中 ??
- ????????ArrayUtils.contains(nums1,? 2 );??
- ??
- ???????? //?將基本數組類型轉為包裝類型 ??
- ????????Integer[]?nums4?=?ArrayUtils.toObject(nums1);??
- ??
- ???????? //?判斷是否為空,length=0或null都屬于 ??
- ????????ArrayUtils.isEmpty(nums1);??
- ??
- ???????? //?并集操作,合并數組 ??
- ????????ArrayUtils.addAll(nums1,?nums2);??
- ??
- ???????? //?增加元素,在下標5中插入10,注意此處返回是新數組 ??
- ????????ArrayUtils.add(nums1,? 5 ,? 1111 );??
- ??
- ???????? //?刪除指定位置元素,注意返回新數組,刪除元素后面的元素會前移,保持數組有序 ??
- ????????ArrayUtils.remove(nums1,? 5 );??
- ??
- ???????? //?刪除數組中值為10的元素,以值計算不以下標 ??
- ????????ArrayUtils.removeElement(nums1,? 10 );??
- ????}??
- }??
- public ? class ?TestMain?{??
- ??
- ???? public ? static ? void ?main(String[]?args)?{??
- ???????? int []?nums1?=?{? 1 ,? 2 ,? 3 ,? 4 ,? 5 ,? 6 ?};??
- ???????? //?通過常量創建新數組 ??
- ???????? int []?nums2?=?ArrayUtils.EMPTY_INT_ARRAY;??
- ??
- ???????? //?比較兩個數組是否相等 ??
- ????????ArrayUtils.isEquals(nums1,?nums2);??
- ??
- ???????? //?輸出數組,第二參數為數組為空時代替輸出 ??
- ????????ArrayUtils.toString(nums1,? "array?is?null" );??
- ??
- ???????? //?克隆新數組,注意此拷貝為深拷貝 ??
- ???????? int []?nums3?=?ArrayUtils.clone(nums1);??
- ??
- ???????? //?截取數組 ??
- ????????ArrayUtils.subarray(nums1,? 1 ,? 2 );??
- ??
- ???????? //?判斷兩個數組長度是否相等 ??
- ????????ArrayUtils.isSameLength(nums1,?nums2);??
- ??
- ???????? //?判斷兩個數組類型是否相等,注意int和Integer比較時不相等 ??
- ????????ArrayUtils.isSameType(nums1,?nums2);??
- ??
- ???????? //?反轉數組 ??
- ????????ArrayUtils.reverse(nums1);??
- ??
- ???????? //?查找數組元素位置 ??
- ????????ArrayUtils.indexOf(nums1,? 5 );??
- ??
- ???????? //?查找數組元素最后出現位置 ??
- ????????ArrayUtils.lastIndexOf(nums1,? 4 );??
- ??
- ???????? //?查找元素是否存在數組中 ??
- ????????ArrayUtils.contains(nums1,? 2 );??
- ??
- ???????? //?將基本數組類型轉為包裝類型 ??
- ????????Integer[]?nums4?=?ArrayUtils.toObject(nums1);??
- ??
- ???????? //?判斷是否為空,length=0或null都屬于 ??
- ????????ArrayUtils.isEmpty(nums1);??
- ??
- ???????? //?并集操作,合并數組 ??
- ????????ArrayUtils.addAll(nums1,?nums2);??
- ??
- ???????? //?增加元素,在下標5中插入10,注意此處返回是新數組 ??
- ????????ArrayUtils.add(nums1,? 5 ,? 1111 );??
- ??
- ???????? //?刪除指定位置元素,注意返回新數組,刪除元素后面的元素會前移,保持數組有序 ??
- ????????ArrayUtils.remove(nums1,? 5 );??
- ??
- ???????? //?刪除數組中值為10的元素,以值計算不以下標 ??
- ????????ArrayUtils.removeElement(nums1,? 10 );??
- ????}??
- }??
????? 還在使用傳統反射嗎?還在被反射的樣板代碼困擾?看commons如何幫助我們簡化反射的工作,從樣板代碼抽身
?
????? ClassUtils
?
- public ? class ?TestMain?{??
- ??
- ???? public ? static ? void ?main(String[]?args)?{??
- ???????? //?獲取Test類所有實現的接口 ??
- ????????ClassUtils.getAllInterfaces(Test. class );??
- ??
- ???????? //?獲取Test類所有父類 ??
- ????????ClassUtils.getAllSuperclasses(Test. class );??
- ??
- ???????? //?獲取Test類所在的包名 ??
- ????????ClassUtils.getPackageName(Test. class );??
- ??
- ???????? //?獲取Test類簡單類名 ??
- ????????ClassUtils.getShortClassName(Test. class );??
- ??
- ???????? //?判斷是否可以轉型 ??
- ????????ClassUtils.isAssignable(Test. class ,?Object. class );??
- ??
- ???????? //?判斷是否有內部類 ??
- ????????ClassUtils.isInnerClass(Test. class );??
- ??
- ????}??
- }??
- public ? class ?TestMain?{??
- ??
- ???? public ? static ? void ?main(String[]?args)?{??
- ???????? //?獲取Test類所有實現的接口 ??
- ????????ClassUtils.getAllInterfaces(Test. class );??
- ??
- ???????? //?獲取Test類所有父類 ??
- ????????ClassUtils.getAllSuperclasses(Test. class );??
- ??
- ???????? //?獲取Test類所在的包名 ??
- ????????ClassUtils.getPackageName(Test. class );??
- ??
- ???????? //?獲取Test類簡單類名 ??
- ????????ClassUtils.getShortClassName(Test. class );??
- ??
- ???????? //?判斷是否可以轉型 ??
- ????????ClassUtils.isAssignable(Test. class ,?Object. class );??
- ??
- ???????? //?判斷是否有內部類 ??
- ????????ClassUtils.isInnerClass(Test. class );??
- ??
- ????}??
- }??
????? ConstructorUtils
?
- public ? class ?TestMain?{??
- ??
- ???? public ? static ? void ?main(String[]?args)?{??
- ??
- ???????? //?獲取參數為String的構造函數 ??
- ????????ConstructorUtils.getAccessibleConstructor(Test. class ,?String. class );??
- ??
- ???????? //?執行參數為String的構造函數 ??
- ????????Test?test?=?(Test)?ConstructorUtils.invokeConstructor(Test. class ,??
- ???????????????? "Hello" );??
- ????}??
- }??
- public ? class ?TestMain?{??
- ??
- ???? public ? static ? void ?main(String[]?args)?{??
- ??
- ???????? //?獲取參數為String的構造函數 ??
- ????????ConstructorUtils.getAccessibleConstructor(Test. class ,?String. class );??
- ??
- ???????? //?執行參數為String的構造函數 ??
- ????????Test?test?=?(Test)?ConstructorUtils.invokeConstructor(Test. class ,??
- ???????????????? "Hello" );??
- ????}??
- }??
????? MethodUtils
?
- public ? static ? void ?main(String[]?args)? throws ?NoSuchMethodException,??
- ????????????IllegalAccessException,?InvocationTargetException?{??
- ???????? //?調用無參方法 ??
- ????????Test?test?=? new ?Test();??
- ????????MethodUtils.invokeMethod(test,? "publicHello" ,? null );??
- ??
- ???????? //?調用一參方法 ??
- ????????MethodUtils.invokeMethod(test,? "publicHello" ,? "Hello" );??
- ??
- ???????? //?調用多參方法 ??
- ????????MethodUtils.invokeMethod(test,? "publicHello" ,? new ?Object[]?{? "100" ,??
- ???????????????? new ?Integer( 10 )?});??
- ??
- ???????? //?調用靜態方法 ??
- ????????MethodUtils.invokeStaticMethod(Test. class ,? "staticHello" ,? null );??
- ????}??
- public ? static ? void ?main(String[]?args)? throws ?NoSuchMethodException,??
- ????????????IllegalAccessException,?InvocationTargetException?{??
- ???????? //?調用無參方法 ??
- ????????Test?test?=? new ?Test();??
- ????????MethodUtils.invokeMethod(test,? "publicHello" ,? null );??
- ??
- ???????? //?調用一參方法 ??
- ????????MethodUtils.invokeMethod(test,? "publicHello" ,? "Hello" );??
- ??
- ???????? //?調用多參方法 ??
- ????????MethodUtils.invokeMethod(test,? "publicHello" ,? new ?Object[]?{? "100" ,??
- ???????????????? new ?Integer( 10 )?});??
- ??
- ???????? //?調用靜態方法 ??
- ????????MethodUtils.invokeStaticMethod(Test. class ,? "staticHello" ,? null );??
- ????}??
????? FieldUtils
?
- public ? class ?TestMain?{??
- ??
- ???? public ? static ? void ?main(String[]?args)? throws ?IllegalAccessException?{??
- ????????Test?test?=? new ?Test( "1" ,? "Ray" ,? "hello" );??
- ??
- ???????? //?以下兩個方法完全一樣,都能獲取共有或私有變量,因為第三個參數都設置了不檢查 ??
- ????????FieldUtils.getDeclaredField(Test. class ,? "username" ,? true );??
- ????????FieldUtils.getField(Test. class ,? "username" ,? true );??
- ??
- ???????? //?讀取私有或公共變量的值 ??
- ????????FieldUtils.readField(test,? "username" ,? true );??
- ??
- ???????? //?讀取靜態變量 ??
- ????????FieldUtils.readStaticField(Test. class ,? "STATIC_FIELD" );??
- ??
- ???????? //?寫入私有或共有變量 ??
- ????????FieldUtils.writeField(test,? "username" ,? "RayRay" ,? true );??
- ??
- ???????? //?寫入靜態變量 ??
- ????????FieldUtils.writeStaticField(Test. class ,? "STATIC_FIELD" ,? "static_value" );??
- ????}??
- }??
- public ? class ?TestMain?{??
- ??
- ???? public ? static ? void ?main(String[]?args)? throws ?IllegalAccessException?{??
- ????????Test?test?=? new ?Test( "1" ,? "Ray" ,? "hello" );??
- ??
- ???????? //?以下兩個方法完全一樣,都能獲取共有或私有變量,因為第三個參數都設置了不檢查 ??
- ????????FieldUtils.getDeclaredField(Test. class ,? "username" ,? true );??
- ????????FieldUtils.getField(Test. class ,? "username" ,? true );??
- ??
- ???????? //?讀取私有或公共變量的值 ??
- ????????FieldUtils.readField(test,? "username" ,? true );??
- ??
- ???????? //?讀取靜態變量 ??
- ????????FieldUtils.readStaticField(Test. class ,? "STATIC_FIELD" );??
- ??
- ???????? //?寫入私有或共有變量 ??
- ????????FieldUtils.writeField(test,? "username" ,? "RayRay" ,? true );??
- ??
- ???????? //?寫入靜態變量 ??
- ????????FieldUtils.writeStaticField(Test. class ,? "STATIC_FIELD" ,? "static_value" );??
- ????}??
- }??
????? 讀者在使用時可能會發現,MethodUtils和ConstructUtils在org.apache.commons.lang.reflect和org.apache.commons.beanutils都存在,但FieldUtils和ClassUtils只在reflect當中存在,因為beanutils提供了另外一種名為PropertyUtils的對屬性存取更為方便的工具,但PropertyUtils不能獲取傳統反射的Field對象,筆者建議MethodUtils和ConstructUtils應該傾向使用beanutils,因為beanutils就是為反射而存在,更專業(雖然提供的方法幾乎一樣),而使用ClassUtils和要獲取傳統的Field對象時使用reflect中的FieldUtils
?
總結:
?
????? commons工具包很多開源組織都有提供,例如google,spring,apache都有各自的工具包,有眾多的選擇,但最終的目的只是為了方便我們程序的開發和維護,簡化我們編寫一些常用的邏輯,提升我們開發的效率,從而達到活在開源,善用開源
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
