`
lendo.du
  • 浏览: 12706 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
社区版块
存档分类
最新评论

在看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里面就不再需要声明这三个方法,这三个方法自动实现了。
分享到:
评论
5 楼 kevinhrw 2009-02-15  
不要统计Collection类型的字段的hashCode就可以解決問題:org.hibernate.LazyInitializationException: illegal access to loading collection,不錯,哈哈.學習了~
4 楼 lendo.du 2008-10-17  
kangsg219 写道

请问一下为什么要实现equals,toString和hashCode这三个方法啊?

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

对象实现了序列化接口得话,也必须实现这3个方法。
3 楼 kangsg219 2008-10-17  
请问一下为什么要实现equals,toString和hashCode这三个方法啊?
2 楼 myyate 2008-10-17  
mengz 写道
在写Hibernate pojo的时候慎用hashcodebuilder

以下是我的遭遇,期望高人帮我解释一下是为什么。
http://mengz.iteye.com/admin/blogs/230903

你把继承BaseEntity的PO的hashCode方法都覆写,记住不要统计Collection类型的字段的hashCode就可以了。
1 楼 mengz 2008-10-16  
在写Hibernate pojo的时候慎用hashcodebuilder

以下是我的遭遇,期望高人帮我解释一下是为什么。
http://mengz.iteye.com/admin/blogs/230903

相关推荐

    commons-lang-2.6.jar包

    commons-lang-2.6.jar包commons-lang-2.6.jar包commons-lang-2.6.jar包commons-lang-2.6.jar包commons-lang-2.6.jar包加源码

    commons-lang-2.4.rar代码及jar文件

    Apache Commons Lang是Java编程语言中的一个实用工具库,它提供了许多在标准Java API中未涵盖的高级字符串和对象处理功能。这个"commons-lang-2.4.rar"压缩包包含了两个子文件,分别是"commons-lang-2.4-bin.zip"和...

    commons-lang3-3.12.0 jar包

    在本例中,我们关注的是`commons-lang3-3.12.0.jar`包,这是Apache Commons Lang项目的最新版本。这个库包含了各种各样的工具类,涵盖了字符串操作、日期和时间处理、数学运算、类型转换等多个方面,极大地丰富了...

    org.apache.commons 常用jar 以及部分源码

    以下是压缩文件的jar包名称: commons-validator-1.3.0.jar commons-pool-1.3.jar commons-net-3.0.jar commons-logging-api-1.1.jar commons-logging-1.0.4.jar commons-lang-2.1.jar commons-io-1.3.2.jar commons...

    commons-lang-2.5 jar包和源码包

    commons-lang-2.5 jar包和源码包

    bcprov-jdk16-145.jar,commons-io-2.0.1.jar,commons-lang-2.5.jar

    7. **commons-logging.jar-master.zip**:这个文件看起来像是Apache Commons Logging库的一个源码版本。Commons Logging是Java日志抽象层,它允许开发者在应用中使用不同的日志框架(如log4j、java.util.logging等)...

    jar包 commons-lang3-3.4.jar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...

    commons-lang3-3.7.jar 和sources.jar

    jar包和源码. Apache Commons包是Java中使用广泛的工具包,很多框架都依赖于这组工具包中的一部分,它提供了我们常用的一些编程需要,JDK没能提供的机能,最大化的减少重复代码的编写。 Commons Lang是对JDK中java....

    commons-httpclient-3.0.jar

    6. **源码可用**:在提供的"commons-httpclient-3.0-sources.jar"中,包含了HttpClient 3.0的源代码,这对于开发者理解和调试代码,以及扩展和定制功能非常有帮助。 7. **与其他Apache Commons组件的集成**:...

    commons-lang-2.5-sources.jar源码jar包

    这个"commons-lang-2.5-sources.jar"源码包包含了Lang项目2.5版本的所有源代码,这对于开发者来说是极其宝贵的资源,因为它允许深入理解内部实现,进行学习、调试或自定义修改。 在Lang库中,有许多关键知识点值得...

    commons-lang3-3.9-tar-压缩包.zip

    Apache Commons Lang是Apache软件基金会开发的一个Java类库,它提供了许多在Java标准库中未包含的实用工具类。"commons-lang3-3.9-tar"是一个压缩包,包含了Lang项目版本3.9的源码和相关文件。这个库特别受欢迎,...

    json应用jar包,json应用的架包:commons-beanutils-1.7.0.jar

    json应用jar包,json应用的...commons-collections-3.2.jar commons-lang-2.4.jar commons-logging-1.1.jar ezmorph-1.0.4.jar json-lib-2.2.2-jdk15.jar json应用jar包,json应用的架包:commons-beanutils-1.7.0.jar

    org.apache.commons.lang包

    在标签中提到了"commons.lang jar包",这表明了这个资源包的核心是`commons-lang.jar`,在更现代的版本中,它演变成了`commons-lang3.jar`,如文件名称列表所示的`commons-lang3-3.7`。这个版本号表示这是Apache ...

    commons-lang3-3.5源码1

    通过深入学习和理解Apache Commons Lang 3.5的源码,开发者可以学习到优秀的编程实践,提升代码质量和效率。源码阅读不仅有助于理解这些工具类的内部工作原理,也有助于我们借鉴和应用到自己的项目中,提升代码的可...

    commons-lang-2.5-sources.jar

    跟java.lang这个包的作用类似,Commons Lang这一组API也是提供一些基础的、通用的操作和处理,如自动生成toString()的结果、自动实现hashCode()和equals()方法、数组操作、枚举、日期和时间的处理等等。

    commons-lang-3-3.1 jar包和源码包

    在这个"commons-lang-3-3.1"版本中,我们找到了一个jar包和源码包,这些都是开发者们进行程序开发的重要资源。这个版本是Lang项目的第3版,第3.1次更新,提供了许多对Java基础类库的补充和优化。 Lang项目提供了一...

    commons-lang-2.3源码包

    commons-lang-2.3的源码包,在ide里面直接连接该资源,就可以查看源代码。

    commons-lang3-3.3.2.rar

    《Apache Commons Lang 3.3.2:源码解析与应用探索》 Apache Commons Lang 是一个Java编程语言的实用工具库,它提供了大量的类和方法来扩展Java的标准库。在这个压缩包"commons-lang3-3.3.2.rar"中,我们主要关注的...

    jedis-2.9.0.jar

    jedis-2.9.0 jar 包,不包含源码,源码下载地址: http://download.csdn.net/download/tan3739/9993938 测试代码: 导入依赖包: commons-lang-2.5.jar commons-pool2-2.4.2.jar jedis-2.9.0 jar public static ...

    commons-beanutils-1.9.2包含全部jar包源码及API文档

    Commons BeanUtils Most Java developers are used to creating Java classes that conform to the JavaBeans naming patterns for property getters and setters. It is natural to then access these methods ...

Global site tag (gtag.js) - Google Analytics