我们继续看
org.apache.commons.lang.builder
这个包。在这里面我们可以找到
7
个类,用于帮助我们实现
Java
对象的一些基础的共有方法。这
7
个类分别是:
CompareToBuilder –
用于辅助实现
Comparable.compareTo(Object)
方法;
EqualsBuilder –
用于辅助实现
Object.equals()
方法;
HashCodeBuilder –
用于辅助实现
Object.hashCode()
方法;
ToStringBuilder –
用于辅助实现
Object.toString()
方法;
ReflectionToStringBuilder –
使用反射机制辅助实现
Object.toString()
方法;
ToStringStyle –
辅助
ToStringBuilder
控制输出格式;
StandardToStringStyle –
辅助
ToStringBuilder
控制标准格式。
我们知道,在实际应用中,其实经常需要在运行过程中判定对象的知否相等、比较、取
hash
、和获取对象基本信息(一般是产生
log
日志)。然而实现这些
compareTo
、
equals
、
hashCode
、
toString
其实并非那么直截了当,甚至稍有不注意就可能造成难以追踪的
bug
,而且这些方法手工维护的话,比较繁琐,也容易出错。于是
Commons Lang
在
builder
这个包中提供了上述辅助类,为我们简化这些方法的实现和维护。
来看一个例子:
package
sean.study.jakarta.commons.lang;
import
java.util.Date;
import
org.apache.commons.lang.builder.CompareToBuilder;
import
org.apache.commons.lang.builder.EqualsBuilder;
import
org.apache.commons.lang.builder.HashCodeBuilder;
import
org.apache.commons.lang.builder.ToStringBuilder;
import
org.apache.commons.lang.builder.ToStringStyle;
public
class BuilderUsage {
public static void main(String[] args) {
Staff staff1 = new Staff(123, "John Smith", new Date());
Staff staff2 = new Staff(456, "Jane Smith", new Date());
System.out.println("staff1's info: " + staff1);
System.out.println("staff2's info: " + staff2);
System.out.println("staff1's hash code: " + staff1.hashCode());
System.out.println("staff2's hash code: " + staff2.hashCode());
System.out.println("staff1 equals staff2? " + staff1.equals(staff2));
}
}
class
Staff implements Comparable {
private long staffId;
private String staffName;
private Date dateJoined;
public Staff() {
}
public Staff(long staffId, String staffName, Date dateJoined) {
this.staffId = staffId;
this.staffName = staffName;
this.dateJoined = dateJoined;
}
public int compareTo(Object o) {
int res = -1;
if (o != null && Staff.class.isAssignableFrom(o.getClass())) {
Staff s = (Staff) o;
res = new CompareToBuilder()
.append(dateJoined, s.getDateJoined())
.append(staffName, s.getStaffName()).toComparison();
}
return res;
}
public boolean equals(Object o) {
boolean res = false;
if (o != null && Staff.class.isAssignableFrom(o.getClass())) {
Staff s = (Staff) o;
res = new EqualsBuilder()
.append(staffId, s.getStaffId())
.isEquals();
}
return res;
}
public int hashCode() {
return new HashCodeBuilder(11, 23).append(staffId).toHashCode();
}
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("staffId", staffId)
.append("staffName", staffName)
.append("dateJoined", dateJoined)
.toString();
}
public Date getDateJoined() {
return dateJoined;
}
public void setDateJoined(Date dateJoined) {
this.dateJoined = dateJoined;
}
public long getStaffId() {
return staffId;
}
public void setStaffId(long staffId) {
this.staffId = staffId;
}
public String getStaffName() {
return staffName;
}
public void setStaffName(String staffName) {
this.staffName = staffName;
}
}
以下是运行结果:
staff1's info: sean.study.jakarta.commons.lang.Staff@190d11[
staffId=123
staffName=John Smith
dateJoined=Sat Jul 30 13:18:45 CST 2005
]
staff2's info: sean.study.jakarta.commons.lang.Staff@1fb8ee3[
staffId=456
staffName=Jane Smith
dateJoined=Sat Jul 30 13:18:45 CST 2005
]
staff1's hash code: 376
staff2's hash code: 709
staff1 equals staff2? false
这些
builder
使用起来都很简单,
new
一个实例,
append
需要参与的信息,最后加上
toComparison
、
isEquals
、
toHashCode
、
toString
这样的结尾即可。相应的,如果你不需要这样级别的控制,也可以使用利用反射机制的版本自动化实现需要的功能,如:
public int compareTo(Object o) {
return CompareToBuilder.reflectionCompare(this, o);
}
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
尤其当我们在项目中不希望过多的参与到对这些对象方法的维护时,采用
Commons
提供的利用反射的这些
API
就成了方便而相对安全的一个方案