- 浏览: 1012698 次
- 性别:
- 来自: 福州
最新评论
-
guanxin2012:
大神,您好。非常感谢您贡献了IKExpression。我们现在 ...
分享开源表达式解析器IK-Expression2.0 -
qqgigas:
LZ,public boolean createUser(LD ...
Sun Directory Server/LDAP学习笔记(二)——API说明及代码样例 -
gao_shengxian:
Hibernate: update T_GX_TEST set ...
优雅Java编程 之 使用Hibernate存储Oracle Spatial对象 -
a78113534:
感谢大神,在安卓里面调用成功了。
发布IK Expression开源表达式解析器 V2.1.0 -
majiedota:
加油
来自开源支持者的第一笔捐赠
代码如下:
上述的 LOC_1 处和 LOC_2 处打印的ID完全相等, LOC_3处输出true(说明对象地址相同),BUT~~ LOC_4处输出是false;
给出FlowToken的equals实现
跟踪发现,实际进入equals的obj参数根本不是外面传入的那个token对象,中间过程被Hinernate的CGLIBLazyInitializer做了代理处理,发生了底层对象的变换。
开始大家都打死不信有这样的BUG,经过对jvm线程和变量编号的反复跟踪,BUG每次都重现。确认CGLIBLazyInitializer确有问题,但目前在国内互联网上没有找到相同的案例。这里提出,供javaeye上的大牛商讨!
如果我们一群人的诊断是对的,hibernate就隐藏了一个相当恐怖的bug咯!!!
还有一件事不明白,就是我在跟踪的时候,就像你说的this.id是有值的,但other.getId()依然返回null。
你上面说的,我基本明白了,直接取属性有问题,但通过get方法取id,应该要返回值才是啊?
通过你现在给的一些条件,很难判断为什么other.getId()依然返回null。毕竟token的所有getter,setter,都已经被hibernate代理了,cglib实现了suround级的方法代理,hibernate可以去调super的对应方法,也可以不调,取决于他的实现,现在需要确定几个事情:
1)token和你跟踪到的equels方法里的other是否同一个对象?如果是,没道理other.getId()为null呀,你在外面已经print一次token.getId()了。
2)other.getId()是否调了super.getId();这个通过你在getId设置断点就可以知道,你所设的断点,我前面也说了都是针对super类的。
一切水落石出了。
在equals方法中,this对象的类是FlowToken,而other对象的类是proxy。this.id是有值的,other.id为null,但使用other.getId()是会取到lazy的id值的(之前估计这里测试的时候有问题,居然没取到值。)
一切如leadyu所预测的那样。
楼主只是说思路清楚了,估计还没开始调试呢。
还有一件事不明白,就是我在跟踪的时候,就像你说的this.id是有值的,但other.getId()依然返回null。
你上面说的,我基本明白了,直接取属性有问题,但通过get方法取id,应该要返回值才是啊?
通过你现在给的一些条件,很难判断为什么other.getId()依然返回null。毕竟token的所有getter,setter,都已经被hibernate代理了,cglib实现了suround级的方法代理,hibernate可以去调super的对应方法,也可以不调,取决于他的实现,现在需要确定几个事情:
1)token和你跟踪到的equels方法里的other是否同一个对象?如果是,没道理other.getId()为null呀,你在外面已经print一次token.getId()了。
2)other.getId()是否调了super.getId();这个通过你在getId设置断点就可以知道,你所设的断点,我前面也说了都是针对super类的。
十分感谢,思路已经清楚了。后面就是沿着思路把问题摸清楚了
还有一件事不明白,就是我在跟踪的时候,就像你说的this.id是有值的,但other.getId()依然返回null。
你上面说的,我基本明白了,直接取属性有问题,但通过get方法取id,应该要返回值才是啊?
通过你现在给的一些条件,很难判断为什么other.getId()依然返回null。毕竟token的所有getter,setter,都已经被hibernate代理了,cglib实现了suround级的方法代理,hibernate可以去调super的对应方法,也可以不调,取决于他的实现,现在需要确定几个事情:
1)token和你跟踪到的equels方法里的other是否同一个对象?如果是,没道理other.getId()为null呀,你在外面已经print一次token.getId()了。
2)other.getId()是否调了super.getId();这个通过你在getId设置断点就可以知道,你所设的断点,我前面也说了都是针对super类的。
感谢提供了这么有用的思路。 确实有这个问题。但就性能而言,尤其是在有了类型约束的Set和Map的容器比较中,我还是偏向于旧的,“带有问题”但高性能的实现。当然,会慎重的考虑到文章中提到的bug(如果出现了逻辑上的不正确,特别会去思考一下,是不是这个问题造成的,呵呵)
用getClass()==getClass()做比较就可以常规短路,这是Eclipse代码生成equals()的实现方法。
如果要支持Hibernate代理对象,可以这样:
至于性能高不高,楼主有空可以自己测一下,我也没细测,但是看过JDK源代码,没什么问题,而且都是引用(内存地址)比较,应该不慢。
感谢提供了这么有用的思路。 确实有这个问题。但就性能而言,尤其是在有了类型约束的Set和Map的容器比较中,我还是偏向于旧的,“带有问题”但高性能的实现。当然,会慎重的考虑到文章中提到的bug(如果出现了逻辑上的不正确,特别会去思考一下,是不是这个问题造成的,呵呵)
还有一件事不明白,就是我在跟踪的时候,就像你说的this.id是有值的,但other.getId()依然返回null。
你上面说的,我基本明白了,直接取属性有问题,但通过get方法取id,应该要返回值才是啊?
你这种逻辑根本不是我要的,对我而言要的业务逻辑是就当id为空时,对象相等比较是无意义的,应设置为不相等。
而且你的写法根本解决不了我提的问题。
不要动不动就说人家的逻辑错了,你根本不知道我要的equals逻辑是啥,又凭什么说我错呢!!
难得有人把事情说清楚了,这样即使被评新手,也认了。
JE上浅薄的人不少啊,还有不少人吧思路放在equals方法的逻辑上,又或者简单的说明proxy中那些谁都明白的概念。
如果问题都那么简单,还用发贴?!
这种问题别不见的人人都碰到并及时发现的。发贴更多是想提醒大家,碰到同样问题的时候,可以很快的醒悟,但很多人在BBS上只是想显摆自己很牛...
动不动就是隐藏和新手,我看je这样走不远(一直希望它能超越CSDN,看来是很困难了)
即使this.id不对,但是楼主先质疑为什么other.getId()为什么是null。(个人觉得other.getId()因该不为空,楼主真的确认了么?)
/** * 判断当前流程实例上下文中,是否存在Blocking(阻挡性)的任务 * 规则 * 1.任务未结束 * 2.任务是必办理的 * 3.当前任务实例的token和执行上下文的token一致 * @param token * @return */ public boolean hasBlockingTaskInstances(FlowToken token) { boolean hasBlockingTasks = false; System.out.println("LOC_1 :" + token.getId()); Set<TaskInstance> taskInstances = flowInstance.getTaskInstances(); if (taskInstances!=null) { Iterator<TaskInstance> iter = taskInstances.iterator(); while ( (iter.hasNext()) && (!hasBlockingTasks)) { System.out.println("LOC_2 : " + taskInstance.getFlowToken().getId()); System.out.println("LOC_3 : " + token == taskInstance.getFlowToken()); System.out.println("LOC_4 : " + token.equals(taskInstance.getFlowToken()); TaskInstance taskInstance = (TaskInstance) iter.next(); if ( (! taskInstance.hasEnded()) //任务未结束 && (taskInstance.getIsBlocking()) //任务是必办理的 && (token!=null) && (token.equals(taskInstance.getFlowToken())) ) { hasBlockingTasks = true; } } } return hasBlockingTasks; }
上述的 LOC_1 处和 LOC_2 处打印的ID完全相等, LOC_3处输出true(说明对象地址相同),BUT~~ LOC_4处输出是false;
给出FlowToken的equals实现
/* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof FlowToken)) return false; final FlowToken other = (FlowToken) obj; if (id == null || other.id == null) { return false; } else if (!id.equals(other.id)) return false; return true; }
跟踪发现,实际进入equals的obj参数根本不是外面传入的那个token对象,中间过程被Hinernate的CGLIBLazyInitializer做了代理处理,发生了底层对象的变换。
开始大家都打死不信有这样的BUG,经过对jvm线程和变量编号的反复跟踪,BUG每次都重现。确认CGLIBLazyInitializer确有问题,但目前在国内互联网上没有找到相同的案例。这里提出,供javaeye上的大牛商讨!
如果我们一群人的诊断是对的,hibernate就隐藏了一个相当恐怖的bug咯!!!
评论
76 楼
linliangyi2007
2009-06-02
再说对于帖子标题的看法!
本人一直认为在互联网上的,在BBS上一切都不必太较真。那种拘泥于标题,拘泥于网络形式,而忽视文章内容的做法,不敢苟同。
现在标题改了,算是迎合网络部分较真人士的观念吧!
做人难,现实生活累人,没想到上个bbs现在也很累人!
本人一直认为在互联网上的,在BBS上一切都不必太较真。那种拘泥于标题,拘泥于网络形式,而忽视文章内容的做法,不敢苟同。
现在标题改了,算是迎合网络部分较真人士的观念吧!
做人难,现实生活累人,没想到上个bbs现在也很累人!
75 楼
linliangyi2007
2009-06-02
leadyu 写道
linliangyi2007 写道
还有一件事不明白,就是我在跟踪的时候,就像你说的this.id是有值的,但other.getId()依然返回null。
你上面说的,我基本明白了,直接取属性有问题,但通过get方法取id,应该要返回值才是啊?
通过你现在给的一些条件,很难判断为什么other.getId()依然返回null。毕竟token的所有getter,setter,都已经被hibernate代理了,cglib实现了suround级的方法代理,hibernate可以去调super的对应方法,也可以不调,取决于他的实现,现在需要确定几个事情:
1)token和你跟踪到的equels方法里的other是否同一个对象?如果是,没道理other.getId()为null呀,你在外面已经print一次token.getId()了。
2)other.getId()是否调了super.getId();这个通过你在getId设置断点就可以知道,你所设的断点,我前面也说了都是针对super类的。
一切水落石出了。
在equals方法中,this对象的类是FlowToken,而other对象的类是proxy。this.id是有值的,other.id为null,但使用other.getId()是会取到lazy的id值的(之前估计这里测试的时候有问题,居然没取到值。)
一切如leadyu所预测的那样。
74 楼
icewubin
2009-05-31
jianfeng008cn 写道
到底原因是什么呢,既然搞清楚了,为何不写写清楚?
楼主只是说思路清楚了,估计还没开始调试呢。
73 楼
jianfeng008cn
2009-05-31
到底原因是什么呢,既然搞清楚了,为何不写写清楚?
72 楼
linliangyi2007
2009-05-31
leadyu 写道
linliangyi2007 写道
还有一件事不明白,就是我在跟踪的时候,就像你说的this.id是有值的,但other.getId()依然返回null。
你上面说的,我基本明白了,直接取属性有问题,但通过get方法取id,应该要返回值才是啊?
通过你现在给的一些条件,很难判断为什么other.getId()依然返回null。毕竟token的所有getter,setter,都已经被hibernate代理了,cglib实现了suround级的方法代理,hibernate可以去调super的对应方法,也可以不调,取决于他的实现,现在需要确定几个事情:
1)token和你跟踪到的equels方法里的other是否同一个对象?如果是,没道理other.getId()为null呀,你在外面已经print一次token.getId()了。
2)other.getId()是否调了super.getId();这个通过你在getId设置断点就可以知道,你所设的断点,我前面也说了都是针对super类的。
十分感谢,思路已经清楚了。后面就是沿着思路把问题摸清楚了
71 楼
leadyu
2009-05-31
linliangyi2007 写道
还有一件事不明白,就是我在跟踪的时候,就像你说的this.id是有值的,但other.getId()依然返回null。
你上面说的,我基本明白了,直接取属性有问题,但通过get方法取id,应该要返回值才是啊?
通过你现在给的一些条件,很难判断为什么other.getId()依然返回null。毕竟token的所有getter,setter,都已经被hibernate代理了,cglib实现了suround级的方法代理,hibernate可以去调super的对应方法,也可以不调,取决于他的实现,现在需要确定几个事情:
1)token和你跟踪到的equels方法里的other是否同一个对象?如果是,没道理other.getId()为null呀,你在外面已经print一次token.getId()了。
2)other.getId()是否调了super.getId();这个通过你在getId设置断点就可以知道,你所设的断点,我前面也说了都是针对super类的。
70 楼
linliangyi2007
2009-05-31
非常赞同使用getClass()==getClass()做比较,看了你推荐的帖子后,正有此意!!
简单且相对了instanceof更合理,但又不用反射每个属性那么耗性能
简单且相对了instanceof更合理,但又不用反射每个属性那么耗性能
69 楼
icewubin
2009-05-31
linliangyi2007 写道
icewubin 写道
要说equals方法逻辑问题,不知道楼主说的哪个部分。
下面这个短路运算就是有问题的,虽然和这贴讨论的东西没有任何关系。
深入研究Java equals方法
下面这个短路运算就是有问题的,虽然和这贴讨论的东西没有任何关系。
if (!(obj instanceof FlowToken)) return false;
深入研究Java equals方法
感谢提供了这么有用的思路。 确实有这个问题。但就性能而言,尤其是在有了类型约束的Set和Map的容器比较中,我还是偏向于旧的,“带有问题”但高性能的实现。当然,会慎重的考虑到文章中提到的bug(如果出现了逻辑上的不正确,特别会去思考一下,是不是这个问题造成的,呵呵)
用getClass()==getClass()做比较就可以常规短路,这是Eclipse代码生成equals()的实现方法。
如果要支持Hibernate代理对象,可以这样:
if (getClass().getPackage() != other.getClass().getPackage()) { return false; }
至于性能高不高,楼主有空可以自己测一下,我也没细测,但是看过JDK源代码,没什么问题,而且都是引用(内存地址)比较,应该不慢。
68 楼
linliangyi2007
2009-05-31
icewubin 写道
要说equals方法逻辑问题,不知道楼主说的哪个部分。
下面这个短路运算就是有问题的,虽然和这贴讨论的东西没有任何关系。
深入研究Java equals方法
下面这个短路运算就是有问题的,虽然和这贴讨论的东西没有任何关系。
if (!(obj instanceof FlowToken)) return false;
深入研究Java equals方法
感谢提供了这么有用的思路。 确实有这个问题。但就性能而言,尤其是在有了类型约束的Set和Map的容器比较中,我还是偏向于旧的,“带有问题”但高性能的实现。当然,会慎重的考虑到文章中提到的bug(如果出现了逻辑上的不正确,特别会去思考一下,是不是这个问题造成的,呵呵)
67 楼
linliangyi2007
2009-05-31
leadyu 写道
首先,我们看看这句:
System.out.println("LOC_3 : " + token == taskInstance.getFlowToken());
这说明token 和taskInstance.getFlowToken() 得到的是同一个对象,都是Cglib的代理类。
那么在这过程中有几个类呢?
第一有FlowToken 和 FlowToken$Proxy类(Cglib创建的),而token是FlowToken$Proxy的实例。
那么Cglib怎么实现代理的呢?它并不会修改原类的任何部分,只会新创建一个类,复写所有父类的public方法
那么在FlowToken$Proxy里面equels就变成:
而,这里最要注意的是在调试工具里面设置的断点一直都是FlowToken该方法的某一行,而不是FlowToken$Proxy类里面的,(这点你可以在debug时注意看stack,可以看到先被FlowToken$Proxy.equels调了以后才到你的断点),所以,你监控的是父类
再看父类的方法:
第一行,为什么不等呢?很简单,这里的this已经是父类的实例,而不是你的token ,所以和传进来的实例自然不等。
那么为什么你看到的传进来的Obj属性全是null,也很简单,因为这个obj也是hibernate的代理出来的一个延时加载类,所有属性都没有的,都是通过get从数据库获得。
不知,这样解释,LZ明白否?
System.out.println("LOC_3 : " + token == taskInstance.getFlowToken());
这说明token 和taskInstance.getFlowToken() 得到的是同一个对象,都是Cglib的代理类。
那么在这过程中有几个类呢?
第一有FlowToken 和 FlowToken$Proxy类(Cglib创建的),而token是FlowToken$Proxy的实例。
那么Cglib怎么实现代理的呢?它并不会修改原类的任何部分,只会新创建一个类,复写所有父类的public方法
那么在FlowToken$Proxy里面equels就变成:
public boolean equels(Object obj){ doCglibHandle... super.equels(obj); doCglibHandle... }
而,这里最要注意的是在调试工具里面设置的断点一直都是FlowToken该方法的某一行,而不是FlowToken$Proxy类里面的,(这点你可以在debug时注意看stack,可以看到先被FlowToken$Proxy.equels调了以后才到你的断点),所以,你监控的是父类
再看父类的方法:
public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof FlowToken)) return false; final FlowToken other = (FlowToken) obj; if (id == null || other.id == null) { return false; } else if (!id.equals(other.id)) return false; return true; }
第一行,为什么不等呢?很简单,这里的this已经是父类的实例,而不是你的token ,所以和传进来的实例自然不等。
那么为什么你看到的传进来的Obj属性全是null,也很简单,因为这个obj也是hibernate的代理出来的一个延时加载类,所有属性都没有的,都是通过get从数据库获得。
不知,这样解释,LZ明白否?
还有一件事不明白,就是我在跟踪的时候,就像你说的this.id是有值的,但other.getId()依然返回null。
你上面说的,我基本明白了,直接取属性有问题,但通过get方法取id,应该要返回值才是啊?
66 楼
icewubin
2009-05-31
要说equals方法逻辑问题,不知道楼主说的哪个部分。
下面这个短路运算就是有问题的,虽然和这贴讨论的东西没有任何关系。
深入研究Java equals方法
下面这个短路运算就是有问题的,虽然和这贴讨论的东西没有任何关系。
if (!(obj instanceof FlowToken)) return false;
深入研究Java equals方法
65 楼
linliangyi2007
2009-05-31
melode11 写道
你自己的equals逻辑错了。只要你对象的id == null,你就不管两个实际上相不相等,直接return false。
if (id == null || other.id == null)
应该改成
if ((id == null || other.id == null) &&!(id ==null&&other.id==null))
if (id == null || other.id == null)
应该改成
if ((id == null || other.id == null) &&!(id ==null&&other.id==null))
你这种逻辑根本不是我要的,对我而言要的业务逻辑是就当id为空时,对象相等比较是无意义的,应设置为不相等。
而且你的写法根本解决不了我提的问题。
不要动不动就说人家的逻辑错了,你根本不知道我要的equals逻辑是啥,又凭什么说我错呢!!
64 楼
linliangyi2007
2009-05-31
leadyu 写道
首先,我们看看这句:
System.out.println("LOC_3 : " + token == taskInstance.getFlowToken());
这说明token 和taskInstance.getFlowToken() 得到的是同一个对象,都是Cglib的代理类。
那么在这过程中有几个类呢?
第一有FlowToken 和 FlowToken$Proxy类(Cglib创建的),而token是FlowToken$Proxy的实例。
那么Cglib怎么实现代理的呢?它并不会修改原类的任何部分,只会新创建一个类,复写所有父类的public方法
那么在FlowToken$Proxy里面equels就变成:
而,这里最要注意的是在调试工具里面设置的断点一直都是FlowToken该方法的某一行,而不是FlowToken$Proxy类里面的,(这点你可以在debug时注意看stack,可以看到先被FlowToken$Proxy.equels调了以后才到你的断点),所以,你监控的是父类
再看父类的方法:
第一行,为什么不等呢?很简单,这里的this已经是父类的实例,而不是你的token ,所以和传进来的实例自然不等。
那么为什么你看到的传进来的Obj属性全是null,也很简单,因为这个obj也是hibernate的代理出来的一个延时加载类,所有属性都没有的,都是通过get从数据库获得。
不知,这样解释,LZ明白否?
System.out.println("LOC_3 : " + token == taskInstance.getFlowToken());
这说明token 和taskInstance.getFlowToken() 得到的是同一个对象,都是Cglib的代理类。
那么在这过程中有几个类呢?
第一有FlowToken 和 FlowToken$Proxy类(Cglib创建的),而token是FlowToken$Proxy的实例。
那么Cglib怎么实现代理的呢?它并不会修改原类的任何部分,只会新创建一个类,复写所有父类的public方法
那么在FlowToken$Proxy里面equels就变成:
public boolean equels(Object obj){ doCglibHandle... super.equels(obj); doCglibHandle... }
而,这里最要注意的是在调试工具里面设置的断点一直都是FlowToken该方法的某一行,而不是FlowToken$Proxy类里面的,(这点你可以在debug时注意看stack,可以看到先被FlowToken$Proxy.equels调了以后才到你的断点),所以,你监控的是父类
再看父类的方法:
public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof FlowToken)) return false; final FlowToken other = (FlowToken) obj; if (id == null || other.id == null) { return false; } else if (!id.equals(other.id)) return false; return true; }
第一行,为什么不等呢?很简单,这里的this已经是父类的实例,而不是你的token ,所以和传进来的实例自然不等。
那么为什么你看到的传进来的Obj属性全是null,也很简单,因为这个obj也是hibernate的代理出来的一个延时加载类,所有属性都没有的,都是通过get从数据库获得。
不知,这样解释,LZ明白否?
难得有人把事情说清楚了,这样即使被评新手,也认了。
JE上浅薄的人不少啊,还有不少人吧思路放在equals方法的逻辑上,又或者简单的说明proxy中那些谁都明白的概念。
如果问题都那么简单,还用发贴?!
这种问题别不见的人人都碰到并及时发现的。发贴更多是想提醒大家,碰到同样问题的时候,可以很快的醒悟,但很多人在BBS上只是想显摆自己很牛...
动不动就是隐藏和新手,我看je这样走不远(一直希望它能超越CSDN,看来是很困难了)
63 楼
icewubin
2009-05-30
62 楼
leadyu
2009-05-30
首先,我们看看这句:
System.out.println("LOC_3 : " + token == taskInstance.getFlowToken());
这说明token 和taskInstance.getFlowToken() 得到的是同一个对象,都是Cglib的代理类。
那么在这过程中有几个类呢?
第一有FlowToken 和 FlowToken$Proxy类(Cglib创建的),而token是FlowToken$Proxy的实例。
那么Cglib怎么实现代理的呢?它并不会修改原类的任何部分,只会新创建一个类,复写所有父类的public方法
那么在FlowToken$Proxy里面equels就变成:
而,这里最要注意的是在调试工具里面设置的断点一直都是FlowToken该方法的某一行,而不是FlowToken$Proxy类里面的,(这点你可以在debug时注意看stack,可以看到先被FlowToken$Proxy.equels调了以后才到你的断点),所以,你监控的是父类
再看父类的方法:
第一行,为什么不等呢?很简单,这里的this已经是父类的实例,而不是你的token ,所以和传进来的实例自然不等。
那么为什么你看到的传进来的Obj属性全是null,也很简单,因为这个obj也是hibernate的代理出来的一个延时加载类,所有属性都没有的,都是通过get从数据库获得。
不知,这样解释,LZ明白否?
System.out.println("LOC_3 : " + token == taskInstance.getFlowToken());
这说明token 和taskInstance.getFlowToken() 得到的是同一个对象,都是Cglib的代理类。
那么在这过程中有几个类呢?
第一有FlowToken 和 FlowToken$Proxy类(Cglib创建的),而token是FlowToken$Proxy的实例。
那么Cglib怎么实现代理的呢?它并不会修改原类的任何部分,只会新创建一个类,复写所有父类的public方法
那么在FlowToken$Proxy里面equels就变成:
public boolean equels(Object obj){ doCglibHandle... super.equels(obj); doCglibHandle... }
而,这里最要注意的是在调试工具里面设置的断点一直都是FlowToken该方法的某一行,而不是FlowToken$Proxy类里面的,(这点你可以在debug时注意看stack,可以看到先被FlowToken$Proxy.equels调了以后才到你的断点),所以,你监控的是父类
再看父类的方法:
public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof FlowToken)) return false; final FlowToken other = (FlowToken) obj; if (id == null || other.id == null) { return false; } else if (!id.equals(other.id)) return false; return true; }
第一行,为什么不等呢?很简单,这里的this已经是父类的实例,而不是你的token ,所以和传进来的实例自然不等。
那么为什么你看到的传进来的Obj属性全是null,也很简单,因为这个obj也是hibernate的代理出来的一个延时加载类,所有属性都没有的,都是通过get从数据库获得。
不知,这样解释,LZ明白否?
61 楼
leadyu
2009-05-30
这个问题有意思,不应该被投新手帖的呀,这个问题并不是大家所想的那样,还要从Cglib的内部机制和java调试JDA两方面造成的。我来说说真正的原因吧。
60 楼
icewubin
2009-05-29
啊,楼主至少还要再次修改两个id的用法,id都换成getId()。
59 楼
melode11
2009-05-29
你自己的equals逻辑错了。只要你对象的id == null,你就不管两个实际上相不相等,直接return false。
if (id == null || other.id == null)
应该改成
if ((id == null || other.id == null) &&!(id ==null&&other.id==null))
if (id == null || other.id == null)
应该改成
if ((id == null || other.id == null) &&!(id ==null&&other.id==null))
58 楼
KimShen
2009-05-28
被拼新手了啊,可惜了
57 楼
icewubin
2009-05-28
Sunteya 写道
可以看到虽然tokenB是通过getter 访问了, 但 tokenA 还是使用id 属性. 这样结果当然还是不对.
即使this.id不对,但是楼主先质疑为什么other.getId()为什么是null。(个人觉得other.getId()因该不为空,楼主真的确认了么?)
发表评论
-
来自开源支持者的第一笔捐赠
2013-01-09 21:15 57772013年1月9号,一个平凡而又不平常的日子! IK中文分词 ... -
发布 IK Analyzer 2012 FF 版本
2012-10-23 17:50 25074首先感谢大家对IK分词器的关注。 最近一段时间正式公司事务最 ... -
发布 IK Analyzer 2012 版本
2012-03-08 11:23 36163新版本改进: 支持分词歧义处理 支持数量词合并 词典支持中英 ... -
CSDN发生严重用户账号泄密事件
2011-12-21 19:21 2564之前有在CSDN注册过的兄弟们,注意了。。。 如果你的邮箱, ... -
一个隐形的java int溢出
2011-08-30 09:44 7555故事的背景: 笔者最近在做一个类SNS的项目,其中 ... -
雷军 :互联网创业的葵花宝典
2011-05-04 10:35 3593博主评: 这片博客很短 ... -
Luci-mint站内搜索实测
2011-04-02 16:18 4135关于Luci-mint 服务器硬 ... -
发布 IK Analyzer 3.2.8 for Lucene3.X
2011-03-04 17:49 14251IK Analyzer 3.2.8版本修订 ... -
TIPS - XML CDATA中的非法字符处理
2011-02-17 15:03 3301XML解析过程中,常遇见CDATA中存在非法字符,尤其在火星文 ... -
对Cassandra的初体验
2010-10-13 17:58 9132作为“云计算”时代的架构设计人员而言,不懂K-V库会被 ... -
Spring + iBatis 的多库横向切分简易解决思路
2010-10-11 13:43 93541.引言 笔者最近在做一个互联网的“类SNS”应用,应用 ... -
发布 IK Analyzer 3.2.5 稳定版 for Lucene3.0
2010-09-08 14:43 5822新版本IKAnnlyzer3.2.8已发布! 地址: http ... -
关于Lucene3.0.1 QueryParser的一个错误
2010-05-21 21:33 2128表达式1: 引用 id:"1231231" ... -
发布 IK Analyzer 3.2.3 稳定版 for Lucene3.0
2010-05-15 14:13 6715IK Analyzer 3.2.3版本修订 在3.2.0版 ... -
windows平台上的nginx使用
2010-01-28 17:13 3404转载自:http://nginx.org/en/docs/wi ... -
发布IKAnnlyzer3.2.0稳定版 for Lucene3.0
2009-12-07 09:27 9574最新3.2.5版本已经推出,http://linliangyi ... -
在Tomcat下以JNDI方式发布JbossCache
2009-12-04 10:57 3828前言: 看过JbossCache的开发手册,发现在Jb ... -
Spring AOP小例子
2009-11-16 10:35 3403PS: 要注明一下,这个是转载滴,之前漏了说鸟,汗死 这里给 ... -
ActiveMQ 5.X 与 Tomcat 集成一(JNDI部署)
2009-11-10 15:15 5648原文地址:http://activemq.apache.org ... -
发布IKAnalyzer中文分词器V3.1.6GA
2009-11-08 23:10 11854IKAnalyzer3.2.0稳定版已经发布,支持Lucene ...
相关推荐
重载equals方法示例重载equals方法示例重载equals方法示例重载equals方法示例重载equals方法示例
例如,public boolean equals(Object o) 是一个正确的重写方法,而 public boolean equals(String o) 是一个重载方法,而不是重写方法。 equals 方法的实现 ------------------------- equals 方法的实现需要遵循...
### equals方法重写知识点解析 #### 一、equals方法简介 `equals`方法是Java语言中Object类的一个重要成员方法,其默认实现是比较两个对象的内存地址是否相同(即是否为同一个对象)。为了使对象之间能够基于内容...
### Java中equals方法隐藏的陷阱 在Java编程中,正确实现`equals`方法至关重要,它不仅影响对象的比较逻辑,还直接关系到集合类(如`HashSet`、`HashMap`等)的行为。本文将深入探讨Java中`equals`方法的一些常见...
### set接口中hashCode和equals方法详解 #### 一、引言 在Java编程语言中,`Set`接口作为集合框架的重要组成部分,在实现无重复元素的数据结构方面扮演着关键角色。为了确保元素的唯一性,`Set`接口依赖于对象的`...
equals()和hashcode()这两个方法都是从object类中继承过来的。当String 、Math、还有Integer、Double。。。。等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法.
Java 对象的toString和equals方法重写 在 Java 中,每个对象都继承自 Object 类,而 Object 类中定义了两个重要的方法:toString() 和 equals()。这两个方法都是非常重要的,它们分别用于对象的字符串表示和对象...
在JavaScript中,`equals`方法并不像在其他某些编程语言中那样是内置的,例如Java。但是,由于JavaScript的灵活性,我们可以自定义一个`equals`函数来实现对象间的深度比较。这个方法通常用于比较两个对象的属性和值...
5. 设定生成Bean的模板,可以选择是否生成equals()、hashCode()、toString()等方法,以及字段的访问级别等。 6. 完成设置后,点击“Finish”按钮,开发工具将自动生成对应的Java Bean类和Hibernate映射文件(.hbm....
equals方法的四个常见陷阱分别是:定义了错误的equals方法签名,重载了equals的但没有同时重载hashCode的方法,建立在会变化字域上的equals定义,不满足等价关系的equals错误定义。下面将对每个陷阱进行详细的解释...
在Java编程语言中,了解如何正确使用`==`和`equals()`方法是非常关键的,因为它们在比较对象和基本类型时有不同的行为。下面将详细解释这两个方法的工作原理、使用场景以及一些常见误区。 首先,`==`运算符主要用于...
在Java编程语言中,比较运算符`==`和`equals()`方法是用来检查两个对象是否相等的,但它们之间存在显著的区别。理解这些差异对于编写正确的代码至关重要。 首先,我们来看`==`运算符。它主要用于基本数据类型的比较...
- 为了避免哈希冲突带来的性能问题,在覆盖`equals()`方法的同时,通常也需要覆盖`hashCode()`方法。 #### 实现示例 以下是一个简单的类`Person`,展示了如何正确覆盖`equals()`和`hashCode()`方法: ```java ...
2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2.javaequals()方法.zip2....
"关于Object中equals方法和hashCode方法判断的分析" 在 Java 中,Object 类提供了两个重要的方法:equals 方法和 hashCode 方法。这两个方法都是用于比较两个对象是否相等的,但它们的实现机理和作用域却有所不同。...
字符串是一个特殊的引用类型,在C#语言中,重载了字符串对象的很多方法,包括`Equals()`方法,使字符串对象用起来就像是值类型一样。这也是为什么在上面的例子中,`a`和`b`的比较结果都是`true`的原因。 需要注意的...
在Java编程语言中,`==`和`equals()`方法是用来比较对象之间关系的两种常见方式,但它们在使用上有着显著的区别。 首先,`==`运算符主要用于比较基本类型(如int、char、byte等)的值是否相等,或者比较引用类型...
### C# Equals 和 GetHashCode 方法重写 在C#编程中,`Equals` 和 `GetHashCode` 方法是非常重要的成员方法,它们对于确保对象的正确比较以及高效地存储和检索对象至关重要。这两个方法通常需要在自定义类中进行...
在Java编程语言中,`equals()` 和 `hashCode()` 方法是Object类中的两个核心方法,所有类都默认继承自Object类。这两个方法在处理对象比较和集合操作时起着至关重要的作用。当我们创建自定义类并需要对对象进行精确...
这里我们将深入探讨`equals()`方法的用法,以及它与`==`的区别,同时解决题目中提出的问题。 **问题一:** 在Java中,`String`类的实例有两种创建方式。一种是直接通过字面量,如`String s1 = "abc";`,这时字符串...