通常,我们在完成一个标准的JavaBean的时候,都需要同时完成equals,toString和hashCode三个方法,一般手动来写的话,实在是很麻烦,特别是如果一个JavaBean中有复杂的数据类型,如集合类型,日期类型等这种情况下,做起来更让人头痛。
于是我用了common-lang.jar这个包里面的一些类来帮我做这三个令人厌烦的工作,比如我现在有一个简单JavaBean,代码如下:
- public class GenericModel implements Serializable {
- private static final long serialVersionUID = 3294254521331173014L;
- protected String id;
- protected Date createTime;
- protected Date updateTime;
- public Date getCreateTime() {
- return createTime;
- }
- public void setCreateTime(Date createTime) {
- this.createTime = createTime;
- }
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public Date getUpdateTime() {
- return updateTime;
- }
- public void setUpdateTime(Date updateTime) {
- this.updateTime = updateTime;
- }
- public boolean equals(Object object) {
- return EqualsBuilder.reflectionEquals(this, object);
- }
- }
public class GenericModel implements Serializable {
private static final long serialVersionUID = 3294254521331173014L;
protected String id;
protected Date createTime;
protected Date updateTime;
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public boolean equals(Object object) {
return EqualsBuilder.reflectionEquals(this, object);
}
}
以上是一个很简单的POJO,要用commons-lang.jar里面的builder来生成这三个方法也很简单,具体做法如下。
1. 生成对应的equals方法:
- public boolean equals(Object obj){
- if (obj == null) {return false;}
- if (obj == this) {return true;}
- if (obj.getClass() != getClass()) {return false;}
- GenericModel gm= (GenericModel) obj;
- return new EqualsBuilder()
- .append(id, gm.getId())
- .append(createTime , gm.getCreateTime())
- .append(updateTime, gm.getUpdateTime())
- .isEquals();
- }
public boolean equals(Object obj){
if (obj == null) {return false;}
if (obj == this) {return true;}
if (obj.getClass() != getClass()) {return false;}
GenericModel gm= (GenericModel) obj;
return new EqualsBuilder()
.append(id, gm.getId())
.append(createTime , gm.getCreateTime())
.append(updateTime, gm.getUpdateTime())
.isEquals();
}
2. 生成对应的hashCode方法:
- public int hashCode() {
- return new HashCodeBuilder(17, 37)
- .append(id)
- .append(createTime)
- .append(updateTime)
- .toHashCode();
- }
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(id)
.append(createTime)
.append(updateTime)
.toHashCode();
}
注意使用HashCodeBuilder的时候,构造方法的两个整数必须不为零且必须为奇数,HashCodeBuilder的构造函数如下:
- public HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) {
- if (initialNonZeroOddNumber == 0) {
- throw new IllegalArgumentException("HashCodeBuilder requires a non zero initial value");
- }
- if (initialNonZeroOddNumber % 2 == 0) {
- throw new IllegalArgumentException("HashCodeBuilder requires an odd initial value");
- }
- if (multiplierNonZeroOddNumber == 0) {
- throw new IllegalArgumentException("HashCodeBuilder requires a non zero multiplier");
- }
- if (multiplierNonZeroOddNumber % 2 == 0) {
- throw new IllegalArgumentException("HashCodeBuilder requires an odd multiplier");
- }
- iConstant = multiplierNonZeroOddNumber;
- iTotal = initialNonZeroOddNumber;
- }
public HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) {
if (initialNonZeroOddNumber == 0) {
throw new IllegalArgumentException("HashCodeBuilder requires a non zero initial value");
}
if (initialNonZeroOddNumber % 2 == 0) {
throw new IllegalArgumentException("HashCodeBuilder requires an odd initial value");
}
if (multiplierNonZeroOddNumber == 0) {
throw new IllegalArgumentException("HashCodeBuilder requires a non zero multiplier");
}
if (multiplierNonZeroOddNumber % 2 == 0) {
throw new IllegalArgumentException("HashCodeBuilder requires an odd multiplier");
}
iConstant = multiplierNonZeroOddNumber;
iTotal = initialNonZeroOddNumber;
}
3. 生成toString方法:
- public String toString() {
- return new ToStringBuilder(this)
- .append("id", id)
- .append("createTime", createTime)
- .append("updateTime", updateTime)
- .toString();
- }
public String toString() {
return new ToStringBuilder(this)
.append("id", id)
.append("createTime", createTime)
.append("updateTime", updateTime)
.toString();
}
好了,这也是一般我们用这个玩意儿的用法,但即使这种情况,我们仍然需要手动维护如此多的属性,有没有一种方式更加简单,可以让代码更简化呢?
有的,再看这几个类里面有这几个方法:
EqualsBuilder.reflectionEquals
HashCodeBuilder.reflectionHashCode
ToStringBuilder.reflectionToString
这几个方法是利用Java的反射机制,自动找到相应的属性,自动生成这几个方法。好了上面的代码就可以改一下了:
- public boolean equals(Object object) {
- return EqualsBuilder.reflectionEquals(this, object);
- }
- public int hashCode(){
- return HashCodeBuilder.reflectionHashCode(this);
- }
- public String toString(){
- return ToStringBuilder.reflectionToString(this);
- }
public boolean equals(Object object) {
return EqualsBuilder.reflectionEquals(this, object);
}
public int hashCode(){
return HashCodeBuilder.reflectionHashCode(this);
}
public String toString(){
return ToStringBuilder.reflectionToString(this);
}
好了,这样看上去就好多了。接下来再多说几句多余的。也是这三个方法的实用价值所在。
我们一般在进行建模的时候,所有的域对象一般都会有一个基类,我上面这个GenericModel也就是一个基类,那么我们项目中的所有域对象都继承自这个基类。同时也就继承了这三个方法。也就是,只要我们新的JavaBean都扩展了GenericModel这个类,那么在我们的新的JavaBean里面就不再需要声明这三个方法,这三个方法自动实现了。