开源工具 — Apache Commons Lang(1)

[size=large]
开源工具系列文章:
Apache Commons Lang(1):[url]http://ray-yui.iteye.com/blog/1953020[/url]
Apache Commons Lang(2):[url]http://ray-yui.iteye.com/blog/1958319[/url]
Apache Commons BeanUtils:[url]http://ray-yui.iteye.com/blog/1961451[/url]
Apache Commons Collections:[url]http://ray-yui.iteye.com/blog/2021484[/url]
Apache Commons IO:[url]http://ray-yui.iteye.com/blog/2023034[/url]
[/size]
[size=large]
相信Apache的大名各位一定不会陌生,Java领域中常用的Ant,Maven,Struts1~2等都是托管在Apache下的项目,而在使用Apache框架的时候,通常要添加框架的依赖包,包括apache-commons系列的依赖包,相信读者对此也不会陌生,而apache-common是非常有用的工具包,包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动
[/size]
[size=large]
一个优秀的类应该重写toString,hashCode,equals,compareTo方法,我们来看一下apache如何带我们简化这些操作,以下示例支持两种形式,一种是通过逐个参数添加从而精细控制那些参数参与比较和输出,另一种是通过反射让全部参数都参与比较和输出

[color=red] Builder系列[/color]
[/size]

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

[size=large]
使用commons能最大程度的简化代码,实现one-line编程,注意使用反射形式的时候,static和transient不会参与比较或输出,要特别注意
[/size]
[size=large]
有些情况下,Arrays满足不到你对数组的操作?不要紧,ArrayUtils帮你

[color=red] ArrayUtils[/color]
[/size]

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

[size=large]
还在使用传统反射吗?还在被反射的样板代码困扰?看commons如何帮助我们简化反射的工作,从样板代码抽身

[color=red] ClassUtils[/color]
[/size]

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

}
}

[size=large]
[color=red] ConstructorUtils[/color]
[/size]

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

[size=large]
[color=red] MethodUtils[/color]
[/size]

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

[size=large]
[color=red] FieldUtils[/color]
[/size]

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

[size=large]
读者在使用时可能会发现,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
[/size]
[size=large]
总结:
commons工具包很多开源组织都有提供,例如google,spring,apache都有各自的工具包,有众多的选择,但最终的目的只是为了方便我们程序的开发和维护,简化我们编写一些常用的逻辑,提升我们开发的效率,从而达到活在开源,善用开源
[/size]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值