SECTION 01 java.lang.* vs commons-lang.*
目前版本为 2.0 , 可以由
首先, 让我们先思考一下, jakarta 为何会有一个 commons-lang 的 opensource 项目呢 ? 在我们使用的 JDK 之中, 都具备有 java.lang.*, 因为默认 import 的原因, 很多人会忽略他的存在, 而 java 历经了 1.1 ~ 1.4 目前正在制定 1.5 的演进來看, 可以使用的 API 是越来越齐全, 但是是否已经完全足够了呢 ?!
很可惜, 因为 JDK 的制定需要通过 JCP 组织的认可, 那是一个各大商业软件公司角力的地方, 而且发布及修改的时间都会非常长久, 因此 commons-lang 就是 jakarta 各个项目常常会使用到的一些功能, 让他可以加强 java.lang.* 的功能~
SECTION 02 org.apache.commons.lang.*
相对于 , commons-lang 就是建立了一些 Utils 来增加他的功能~ 例如 ArrayUtils, BooleanUtils, CharSetUtils, ClassUtils, NumberUtils, ObjectUtils, StringUtils, SystemUtils 及 WordUtils 等等... 我们拿常用的 StringUtils 来看, 他提供了很多不错的功能.
例如在 jdk1.3 String 不存在 replaceAll(String regex, String replacement), StringUtils 就提供了 replaceChars(String str, String searchChars, String replaceChars) 来处理全部替换的功能.
NULL 这个空值常常会导致程序的 NullPointerException, 在撰写接收使用者 request 程序的时候会特別麻烦, 需要多输入 null 的检查, 不如使用 EMPTY 空字串来得方便, 所以我们可以将一些 StringUtils.defaultString(request.getParameter("xxx")) 来确保不是 NULL.. 各位可以查询一下 API, 里面有很多 methods 都是讨论 null 如何处理的方法及原则.
此外, SystemUtils 就是增加了一些 java 系统上面的处理, 例如检查 java 的版本 isJavaVersionAtLeast , 执行的作业系统等等..
SECTION 03 org.apache.commons.lang.builder
Builder.. 是建立一些特殊功能的子项目, 这也是我认为 commons-lang 非常不错的子项目.. 最重要的应用就是我们在做项目时, 商业逻辑的 VO 都是标准的 javabean 写法, 会有一些 getter 与 setter, 可以通过 reflection 来处理 JavaBean 的变化与取值..
- CompareToBuilder: 加强实现 Comparable.compareTo(Object) methods.
在 VO 的排序处理中, 我们常常会比较 Object 中的某个值或字符串, 可以利用 Comparable 来处理, 或是利用下面的方法.. public class MyClass {
String field1;
int field2;
boolean field3;
...
public int compareTo(Object o) {
MyClass myClass = (MyClass) o;
return new CompareToBuilder()
.appendSuper(super.compareTo(o)
.append(this.field1, myClass.field1)
.append(this.field2, myClass.field2)
.append(this.field3, myClass.field3)
.toComparison();
}
}
如果, 你需要对整个 Object 做比较呢, 那么就直接写简单的 reflectionCompare, 就可以得到每个 field 的比较结果了 ~ public int compareTo(Object o) {
return CompareToBuilder.reflectionCompare(this, o);
}
- EqualsBuilder: 加强实现 Object.equals(Object) methods.
EqualsBuilder 和 CompareToBuilder 类似, 只是加强实现相等的部分, 如果你对两个对象的比较只是限于某些 field 得比较, 那么就可以利用以下的方法来确认是否相等.. public boolean equals(Object o) {
if ( !(o instanceof MyClass) ) {
return false;
}
MyClass rhs = (MyClass) o;
return new EqualsBuilder()
.appendSuper(super.equals(o))
.append(field1, rhs.field1)
.append(field2, rhs.field2)
.append(field3, rhs.field3)
.isEquals();
}
当然, 你也可以对 Object 內存的所有属性做比较是否相等.. public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
- HashCodeBuilder: 加强实现 Object.hashCode() methods.
在 Class 之中最好存在一个 hashCode 让它根据內存数值生成具有唯一性的 hash 判断值, 不过建立一个 HashCode 生成器可能非常麻烦, 不用烦恼, 使用 commons-lang 将会让程序更简单 ~ public class Person {
String name;
int age;
boolean isSmoker;
...
public int hashCode() {
//你可以写死 ( hard-coded), 随机产生, 只要非零并且为奇数的值就可以了.
//最好是每个 class 都具有不同的 hashcode 值.
return new HashCodeBuilder(17, 37).
append(name).
append(age).
append(smoker).
toHashCode();
}
}
如果所有属性都要产生, 可以通过 reflection 来处理. public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
- ToStringBuilder: 加强实现 Object.toString() methods.
我们会要求工程师在所有的 VO 都要撰写 toString() 覆写 Object.toString(), 因为这样 debug 的時候才不需要重复地去寻找错误的地方. public class Person {
String name;
int age;
boolean isSmoker;
...
public String toString() {
return new ToStringBuilder(this).
append("name", name).
append("age", age).
append("smoker", smoker).
toString();
}
}
如果所有属性都要产生, 则直接使用 reflectionToString(this) 也可以, 而且, 如果要去 debug 其他公司所撰写的程序, 也可以通过 ToStringBuilder.reflectionToString(XyzObject); 来了解他对象內数值的状态~ public String toString() {
return ToStringBuilder.reflectionToString(this);
}
- ReflectionToStringBuilder: 使用 reflection 加强实现 Object.toString() methods .
ReflectionToStringBuilder 是 extends ToStringBuilder, 而他就是通过 reflection 来完成 toString 的, 他的使用方法很类似 ToStringBuilder.reflectionToString public String toString() {
return ReflectionToStringBuilder.toString(this);
}
不过, 如果你不希望显示 password 的 field, 可以通过 accept 来处理不显示的数值. public String toString() {
return (new ReflectionToStringBuilder(this) {
protected boolean accept(Field f) {
return super.accept(f) && !f.getName().equals("password");
}
}).toString();
}
SECTION 04 org.apache.commons.lang.enum
这个 enumeration 是专为原本是 c 语言开发者所建立的 sub-package, 只需要 extends Enum, 就可以简单地取得 Enum, Map, List 以及 Iterator 等等~ public final class ColorEnum extends Enum {
public static final ColorEnum RED = new ColorEnum("Red");
public static final ColorEnum GREEN = new ColorEnum("Green");
public static final ColorEnum BLUE = new ColorEnum("Blue");
private ColorEnum(String color) {
super(color);
}
public static ColorEnum getEnum(String color) {
return (ColorEnum) getEnum(ColorEnum.class, color);
}
public static Map getEnumMap() {
return getEnumMap(ColorEnum.class);
}
public static List getEnumList() {
return getEnumList(ColorEnum.class);
}
public static Iterator iterator() {
return iterator(ColorEnum.class);
}
}
只需要通过 ColorEnum.getEnum(ColorEnum.RED) 就可以取得 enumeration.
SECTION 05 其他
其他如 exception, math, time 因为我用到的机会不大, exception 的部分大多是增加了一些 Nestable 的 Exception 处理, math 则是 Range 及 计算上的工具, 最后, time 就是一些日期时间的工具, 不过 StopWatch 蛮有趣的, 他是一个计时器, 通常我们在计算执行时间, 可以使用. 大家可以自行参考 API, 如果有需要可以直接使用.
SECTION 06 结论
jakarta commons-lang 提供了许多有用的开发工具, 尤其 null 及 Reflection 对一般工程师是一个麻烦的开发设计, 因此, 如果可以通过 commons-lang 来解决基础的问题, 我们可以更容易运用 java 在大型的开发之中. |