论坛首页 入门技术论坛

Hibernate Bean的Equals方法重载问题

浏览 15519 次
该帖已经被评为新手帖
作者 正文
   发表时间:2009-05-27  
谢谢楼上再解释了下,前面有人已经解释过了。
0 请登录后投票
   发表时间:2009-05-27  
icewubin 写道
虽然我不会投楼主新手帖,但是楼主完全应该在发帖前多测试几下嘛。

这种情况,楼主只要在equals方法中打印几行,几个判断的结果很容易就能发现是哪一个判断返回false。至少到这一步你能知道是other.id不是你预期的结果。


兄弟,你没看贴啊,在发贴前做了完整的跟踪的。你看看原帖的说明吧,而且在equals方法内也做跟踪的,发现对象被替换了。

目前按照楼上的说法,使用getID仍然有问题,还是没有解决!!看来不是方法覆盖那么简单的现象了!
0 请登录后投票
   发表时间:2009-05-27  
rrsy23 写道
从这个问题看LZ对java的equlas与hashcode没有理解清楚;
这两个方法是留个自己实现的;

我完全可以写个equals永远返回false,hashcode永远返回一样;

说个实际点的吧;
set 放进去的东西能找到吗?
package com.bobo;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class TestMain {
public static void main(String[] args) {
new TestMain().test1();

}

public void test1() {

Set set = new HashSet();

set.add(new A());
// false
System.out.println(set.contains(new A()));

set.add(new B());
// true
System.out.println(set.contains(new B()));

set.add(new C());
// true
System.out.println(set.contains(new C()));

A a = new A();
set.add(a);
// true
System.out.println(set.contains(a));

B b = new B();
set.add(b);
// true
System.out.println(set.contains(b));

C c = new C();
set.add(c);
// 大部分情况下是false
System.out.println(set.contains(c));

}

class A {

}

class B {

@Override
public int hashCode() {

return 1;
}

@Override
public boolean equals(Object obj) {

return true;
}

}

class C {

@Override
public int hashCode() {
return new Random().nextInt();
}

@Override
public boolean equals(Object obj) {
return true;
}

}

}
理解哈吧,研究哈吧;其实很多书上也讲了;
关键是你思考没有,研究没有;


兄弟们,不要动不动就否定别人不理解hashcode和equals,去看看我的blog吧,本人对java的Set,Map以及相关的equals,hashCode是有相当深入的研究的,如果问题都这么简单,我不会提出来的。

浮躁啊~~je上充满浮躁!!
0 请登录后投票
   发表时间:2009-05-27  
linliangyi2007 写道
icewubin 写道
虽然我不会投楼主新手帖,但是楼主完全应该在发帖前多测试几下嘛。

这种情况,楼主只要在equals方法中打印几行,几个判断的结果很容易就能发现是哪一个判断返回false。至少到这一步你能知道是other.id不是你预期的结果。


兄弟,你没看贴啊,在发贴前做了完整的跟踪的。你看看原帖的说明吧,而且在equals方法内也做跟踪的,发现对象被替换了。

目前按照楼上的说法,使用getID仍然有问题,还是没有解决!!看来不是方法覆盖那么简单的现象了!


还没有解决?
你跟踪下equals看看
0 请登录后投票
   发表时间:2009-05-27  
KimShen 写道
linliangyi2007 写道
icewubin 写道
虽然我不会投楼主新手帖,但是楼主完全应该在发帖前多测试几下嘛。

这种情况,楼主只要在equals方法中打印几行,几个判断的结果很容易就能发现是哪一个判断返回false。至少到这一步你能知道是other.id不是你预期的结果。


兄弟,你没看贴啊,在发贴前做了完整的跟踪的。你看看原帖的说明吧,而且在equals方法内也做跟踪的,发现对象被替换了。

目前按照楼上的说法,使用getID仍然有问题,还是没有解决!!看来不是方法覆盖那么简单的现象了!


还没有解决?
你跟踪下equals看看


跟踪结果是,同样一句的taskInstance.getFlowToken()在equals方法外取的对象,在java虚拟机的编号和equals方法内部取到的对象根本不一样,换句话中,我们在给equals方法传入参数时,到了equals方法内部的那个对象不是外面传入的那个参数!!!!
很匪夷所思吧~~
0 请登录后投票
   发表时间:2009-05-27   最后修改:2009-05-27
linliangyi2007 写道
跟踪结果是,同样一句的taskInstance.getFlowToken()在equals方法外取的对象,在java虚拟机的编号和equals方法内部取到的对象根本不一样,换句话中,我们在给equals方法传入参数时,到了equals方法内部的那个对象不是外面传入的那个参数!!!!
很匪夷所思吧~~

你这段话早点表达清楚就不会让很多人绕弯弯了。

你说那个“使用getID也不行”,能把修改过的equals的代码再贴出来看看么?
0 请登录后投票
   发表时间:2009-05-27  
icewubin 写道
linliangyi2007 写道
跟踪结果是,同样一句的taskInstance.getFlowToken()在equals方法外取的对象,在java虚拟机的编号和equals方法内部取到的对象根本不一样,换句话中,我们在给equals方法传入参数时,到了equals方法内部的那个对象不是外面传入的那个参数!!!!
很匪夷所思吧~~

你这段话早点表达清楚就不会让很多人绕弯弯了。

你说那个“使用getID也不行”,能把修改过的equals的代码再贴出来看看么?


   1. /* (non-Javadoc) 
   2.  * @see java.lang.Object#equals(java.lang.Object) 
   3.  */  
   4. @Override  
   5. public boolean equals(Object obj) {  
   6.     if (this == obj)  
   7.         return true;  
   8.     if (obj == null)  
   9.         return false;  
  10.     if (!(obj instanceof FlowToken))  
  11.         return false;  
  12.     final FlowToken other = (FlowToken) obj;  
  13.     if (id == null || other.getId() == null) {  
  14.         return false;  
  15.     } else if (!id.equals(other.getId()))  
  16.         return false;  
  17.     return true;  
  18. }  


修改过的equals。这个方法跟踪的时候other.getId() 居然为null,而在equals外,我是能取到这个对象的id的。
0 请登录后投票
   发表时间:2009-05-27   最后修改:2009-05-27
建议先在equals方法中,加入如下两句话,看看结果:
System.out.println(this.getClass());
System.out.println(other.getClass());

顺带确认一下你传进来的token参数本身是否是代理对象,是的话,这个equals有可能也被CGLib动了写手脚(我瞎猜的)。

然后主要测试代码如下修改:
FlowToken tokenOther = taskInstance.getFlowToken();

然后三个打印都使用这个tokenOther的引用,看看结果。


0 请登录后投票
   发表时间:2009-05-27  
icewubin 写道
建议先在equals方法中,加入如下两句话,看看结果:
System.out.println(this.getClass());
System.out.println(other.getClass());

顺带确认一下你传进来的token参数本身是否是代理对象,是的话,这个equals有可能也被CGLib动了写手脚(我瞎猜的)。

然后主要测试代码如下修改:
FlowToken tokenOther = taskInstance.getFlowToken();

然后三个打印都使用这个tokenOther的引用,看看结果。




你的猜测是对的,在跟踪调试中,可以很明显的看到,调用equals方法时,CGLib接入了其中,这也正是我写这篇blog的原因,我们还请了公司的C++权威来协助跟踪,确定我们不是眼花了,或者代码错误,确实是被代理替换了对象。但我们不知道CGLib在怎样一种情况下,会发生这样的异常。(肯定不是每次都发生的,否则问题早就被发现了,呵呵)
0 请登录后投票
   发表时间:2009-05-27   最后修改:2009-05-27
cglib 替换对象是很正常的,你能不能明确的说明错在哪了?你的替换了对象是什么意思啊?这帖子看得真冒火。
ps:你一个劲强调自己水平好有意义嘛!
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics