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

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