java 重写equals方法 最佳实践 Java@Override equals():当this.getClass()!=o.getClass()失败
https://www.5axxw.com/questions/content/dn5jai
我在MyClass中有一个@Override for equals():
public class MyClass extends MySuperClass
{
...
@Override
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( o == null || this.getClass() != o.getClass() )
{
return false;
}
if ( !super.equals( o ) )
{
return false;
}
MyClass that = ( MyClass ) o;
return this.var1.equals( that.var1 ) && this.var2.equals( that.var2 );
}
...
}
相当标准。事实上,它遵循Java最佳实践。在以后的生活中,我在另一个sub-package类(我的控制器类)中有这个:
...
package com.a.b.api.controllers;
...
import com.a.b.jpa.models.MyClass;
...
MyClass myObject1 = new MyClass( var1, var2 );
MyClass myObject2 = this.myClassRepository.getById( 1 ); // SpringBoot/Jpa/Hibernate
if ( myObject2.equals( myObject1 ) )
{
...do something...
}
...
this.myClassRepository.save( myObject1 );
...
我的问题是。equals()在这里总是失败:
if ( o == null || this.getClass() != o.getClass() )
因为java说this.getClass()和o.getClass()不相等。当我调试代码(在Intellij IDEA2022.1 UE中)时,我看到:
this.getClass() = MyClass@13706
but
o.getClass = com.a.b.jpa.models.MyClass@8f7462
但他们是同一个阶级!几乎每一本Java书籍、教程、博客、Intellij IDEA等都演示了这一点。这样。我在Ubuntu20.04.4 LTSjava-14-openjdk-amd64和java-17-openjdk-amd64中尝试过这个方法,得到了相同的结果。
我做错了什么?
happy hongs在回答中正确地指出:
myObject2是一个代理类的实例,由Hibernate在运行时使用Byte Buddy生成。生成的代理截获所有方法调用,这就是getClass()返回不同结果的原因。
我真的不想使用instanceof,因为这被认为是不好的做法,所以我开始四处闲逛,偶然发现了一个类似的问题。他们的解决方案是在类声明中添加最后一个关键字。我认为这无关紧要,但尝试了一下——成功了!添加最后一个关键字
if ( o == null || this.getClass() != o.getClass() )
and
if ( o == null || !this.getClass().equals( o.getClass() ) )
正常工作。我的班级代码是:
final public class MyClass extends MySuperClass
{
...
@Override
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( o == null || !this.getClass().equals( o.getClass() ) )
{
return false;
}
if ( !super.equals( o ) )
{
return false;
}
MyClass that = ( MyClass ) o;
return this.var1.equals( that.var1 ) && this.var2.equals( that.var2 );
}
...
}
谢谢大家的帮助!非常感谢快乐歌曲为我指明了正确的方向!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2021-01-11 encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。
2021-01-11 SQL 语句
2021-01-11 $("p").fadeOut("fast")设置淡出效果
2021-01-11 神奇的 toLocaleString
2021-01-11 获得当前时间的毫秒级别datetime.now.tostring(yyyyMMddHHmmssfff)
2021-01-11 浏览器 显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字。window.prompt()
2021-01-11 JS字符串转换为JSON对象的四种方法