读书人

在看commons-lang.jar包源码时分的一些

发布时间: 2012-10-31 14:37:31 作者: rapoo

在看commons-lang.jar包源码时候的一些发现及实践
通常,我们在完成一个标准的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);    }}


以上是一个很简单的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();}


2. 生成对应的hashCode方法:
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;}


3. 生成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);}


好了,这样看上去就好多了。接下来再多说几句多余的。也是这三个方法的实用价值所在。

我们一般在进行建模的时候,所有的域对象一般都会有一个基类,我上面这个GenericModel也就是一个基类,那么我们项目中的所有域对象都继承自这个基类。同时也就继承了这三个方法。也就是,只要我们新的JavaBean都扩展了GenericModel这个类,那么在我们的新的JavaBean里面就不再需要声明这三个方法,这三个方法自动实现了。 1 楼 mengz 2008-10-16 在写Hibernate pojo的时候慎用hashcodebuilder

以下是我的遭遇,期望高人帮我解释一下是为什么。
http://mengz.iteye.com/admin/blogs/230903 2 楼 myyate 2008-10-17 mengz 写道在写Hibernate pojo的时候慎用hashcodebuilder

以下是我的遭遇,期望高人帮我解释一下是为什么。
http://mengz.iteye.com/admin/blogs/230903
你把继承BaseEntity的PO的hashCode方法都覆写,记住不要统计Collection类型的字段的hashCode就可以了。 3 楼 kangsg219 2008-10-17 请问一下为什么要实现equals,toString和hashCode这三个方法啊? 4 楼 lendo.du 2008-10-17 kangsg219 写道
请问一下为什么要实现equals,toString和hashCode这三个方法啊?

equals是用来比较对象的值是否相等撒,如果不实现,用的是Object.equals方法,他只会比较两个对象的引用地址是否相等。
toString是方便直接输出对象的内容。
hashCode如果不实现,那么类也是使用Object.hashCode方法,但是一旦你实现了自己的equals方法,那么就必须实现hashCode方法,因为如果两个对象equals的结果为true得话,那么他们的hashCode也应该一致。

对象实现了序列化接口得话,也必须实现这3个方法。 5 楼 kevinhrw 2009-02-15 不要统计Collection类型的字段的hashCode就可以解:org.hibernate.LazyInitializationException: illegal access to loading collection,不,哈哈.了~

读书人网 >软件架构设计

热点推荐