论坛首页 入门技术论坛

Hibernate Bean的Equals方法重载问题

浏览 15515 次
该帖已经被评为新手帖
作者 正文
   发表时间:2009-05-27  
翻阅Cglib文档 提供如下分析给你
public class Test {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public boolean equals(Object o) {
Test test = (Test) o;
System.out.println(test.id);
System.out.println(test.getId());
return this.id == test.getId() ? true : false;
}
}

//模拟Cglib
public class Test2 extends Test {
private Integer id;
}

public class Equal {
public static void main(String[] args) {
Test test1 = new Test();
Test test2 = new Test();
test1.setId(1);
test2.setId(1);

Test2 test3 = new Test2();
test2.setId(1);

System.out.println(test1.equals(test2));
System.out.println(test1.equals(test3));
}
}

这下你应该知道为什么了


0 请登录后投票
   发表时间:2009-05-27  
上面的同学,麻烦中文描述下,是指“cglib过,私有属性直接调用不会返回正确的结果,还是方法调用才会正确,属性调用不正确了?”,科普下,谢谢
0 请登录后投票
   发表时间:2009-05-27  
jianfeng008cn 写道
上面的同学,麻烦中文描述下,是指“cglib过,私有属性直接调用不会返回正确的结果,还是方法调用才会正确,属性调用不正确了?”,科普下,谢谢


Cglib的原理是继承.也就是为什么final属性不能用Cglib的原因

Test2 继承 Test
Test有private Id字段
Test2就自动生成private Id字段

public void getValue(Test o)
//如果Test2作为属性传入getValue
//那么根据多态
{
o.id; //调用的是Test2父类的id
o.getId();//调用的Test2本身的id
}

所以他使用order.id 自然返回的是Cglib代理类父类(也就是被代理类)的id
自然是 0
7 请登录后投票
   发表时间:2009-05-27  
KimShen 写道


session.load 这类方法本来就返回的Cglib代理你不会刚知道吧

来分析下equals
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
// 以上2条可以不用测试if (!(obj instanceof FlowToken))
return false;
// System.out.println(obj.getClass()) 正确返回Cglib代理 这条正确通过
final FlowToken other = (FlowToken) obj;
// 问题来了 other.id? 难道你用的public Integer id?
if (id == null || other.id == null) {
// 就是这条出错了
// 测试结果id=0

return false;
} else if (!id.equals(other.id))
return false;
return true;
}


原因分析:
当一个类实例传入到另一个同类型的类中可以直接调用他的private字段
p.setId(1);
public void setPeople(People p)
{
p.id=100;
System.out.println(p.id);
//输出100
System.out.println(p.getId());
//输出1
}
具体为什么我也从来没在什么地方看到过,希望了解的指点一下

所以other.id是问题的关键
other.getId()看看


	public String getId() {
		return this.id;
	}


ID是一个String型的,所以使用==null判断是没问题的。我当然知道cglib会返回代理,但想不通equals方法调用的时候,proxy对象的行为太奇怪了。
0 请登录后投票
   发表时间:2009-05-27  
linliangyi2007 写道
KimShen 写道


session.load 这类方法本来就返回的Cglib代理你不会刚知道吧

来分析下equals
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
// 以上2条可以不用测试if (!(obj instanceof FlowToken))
return false;
// System.out.println(obj.getClass()) 正确返回Cglib代理 这条正确通过
final FlowToken other = (FlowToken) obj;
// 问题来了 other.id? 难道你用的public Integer id?
if (id == null || other.id == null) {
// 就是这条出错了
// 测试结果id=0

return false;
} else if (!id.equals(other.id))
return false;
return true;
}


原因分析:
当一个类实例传入到另一个同类型的类中可以直接调用他的private字段
p.setId(1);
public void setPeople(People p)
{
p.id=100;
System.out.println(p.id);
//输出100
System.out.println(p.getId());
//输出1
}
具体为什么我也从来没在什么地方看到过,希望了解的指点一下

所以other.id是问题的关键
other.getId()看看


	public String getId() {
		return this.id;
	}


ID是一个String型的,所以使用==null判断是没问题的。我当然知道cglib会返回代理,但想不通equals方法调用的时候,proxy对象的行为太奇怪了。


不好意思 是我注解打错了地方...

//问题来了 other.id? 难道你用的public Integer id?[/color]
(!id.equals(other.id))

原因我上面已经说过了
同理对于你上面的null判断
0 请登录后投票
   发表时间:2009-05-27  
KimShen 写道
jianfeng008cn 写道
上面的同学,麻烦中文描述下,是指“cglib过,私有属性直接调用不会返回正确的结果,还是方法调用才会正确,属性调用不正确了?”,科普下,谢谢


Cglib的原理是继承.也就是为什么final属性不能用Cglib的原因

Test2 继承 Test
Test有private Id字段
Test2就自动生成private Id字段

public void getValue(Test o)
//如果Test2作为属性传入getValue
//那么根据多态
{
o.id; //调用的是Test2父类的id
o.getId();//调用的Test2本身的id
}

所以他使用order.id 自然返回的是Cglib代理类父类(也就是被代理类)的id
自然是 0


非常感谢,我也怀疑过直接属性调用的问题,但没有深入思考。从你的分析上,很可能就是这样的原因了。我去实践一下吧。感谢提供了一个合理的思路
0 请登录后投票
   发表时间:2009-05-27  
KimShen 写道

Test有private Id字段


Test的id应该是public的吧
0 请登录后投票
   发表时间:2009-05-27  
jianfeng008cn 写道
KimShen 写道

Test有private Id字段


Test的id应该是public的吧


private 的,因为是在同一个类的内部,所以private可以直接引用
0 请登录后投票
   发表时间:2009-05-27  
既然被proxy代理过的,那么目前的状况就正常了。
0 请登录后投票
   发表时间:2009-05-27  
靠这也叫新手帖!!
javaeye上有几个新手提这样的问题啊!!
提问题也要有层次好啵?动不动就评新手帖,无语!
0 请登录后投票
论坛首页 入门技术版

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