当前位置: 首页 > 知识库问答 >
问题:

Java@覆盖等于():当this.get类() ! = o.get类()失败但不应该

松英叡
2023-03-14

我在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最佳实践
在以后的生活中,我在另一个子包类(我的控制器类)中有这个:

...
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说。getClass()和o.getClass()不相等。当我调试代码(在Intellij IDEA 2022.1 UE中)时,我看到:

this.get类()=MyClass@13706

但是

o、 getClass=com。a、 b.jpa。模型。MyClass@8f7462

但他们是同一个阶级!几乎每一本Java书籍、教程、博客、Intellij IDEA等都演示了这一点。这样。我在Ubuntu 20.04.4 LTS java-14-openjdk-amd64和java-17-openjdk-amd64中尝试过这个方法,得到了相同的结果。

我做错了什么?

共有2个答案

公良弘毅
2023-03-14

我对JPA实体(如本文所述)使用标准equalshashcode实现:

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (!(o instanceof MyClass)) {
        return false;
    }
    MyClass other = (MyClass) o;
    return id != null && id.equals(other.getId());
}


@Override
public int hashCode() {
    return getClass().hashCode();
}
梁新觉
2023-03-14

myObject2是一个代理类的实例,在运行时由HiberNate使用Byte Buddy生成。生成的代理拦截所有方法调用,这就是为什么getClass()返回不同的结果。

作为getClass()的替代方法,使用instanceof可能是另一种方法:

if ( !(this instanceof MyClass && o instanceof MyClass) )
{
   return false;
}

但是请记住,instanceof有其缺点。它违反了对称原则。

首先不应该比较这些对象,因为新对象应该不同于具有持久状态的Hibernate管理对象。

 类似资料:
  • 问题内容: 在编写自己的类时,是否总是有必要重写? 如果我不这样做,它将自动检查所有字段是否相同?还是只是检查两个变量是否指向同一个对象? 问题答案: 如果正在编写将要以某种方式比较其对象的类,则应重写和方法。 不提供显式方法将导致从超类继承该方法的行为,并且在超类为类的情况下,它将成为Java API规范中针对该类设定的行为。 提供方法的一般约定可以在该类的文档中找到,特别是and 方法的文档。

  • 我正在开发一个Java中的图形库(https://github.com/aisthesis/java-graph2012 完整的上下文),并且需要覆盖权重边缘类的hashCode(),其中边缘不定向。也就是说,我设置了我的 equals() 覆盖方法,以便对于 2 个加权边 e1 和 e2,如果以下条件之一成立(from() 和 to() 方法返回边的尾部和头顶点),则它们相等: e1.从() =

  • 问题内容: 我有下面的课程 我想创建一个全局队列,如果该对象存在于队列B中,则应该允许添加该全局队列,但反之则不行。因此,在#1之前,我循环遍历set内的元素,并在元素上添加了false。 但是1正在调用B.equals(C),它返回true,因此mySet在此行之后只有一个C对象 2再次调用返回真值的B.equals(C)并删除现有对象C。在这种情况下,它不是C.equals(B)吗?我希望这条

  • 问题内容: 我有一个抽象类,应该实现一个公共字段,该字段是一个接口或另一个抽象类。 像这样的东西: 现在我有另一个专门的类容器: Java的让我编译这个,和我想象的领域中被自动重载领域的......这些问题是:我是对这个?孩子的自动“超载”会发生吗? 而且,更重要的问题是,如果我还有另一个这样的课: 会返回1还是2?我的意思是容器字段将称为通用字段还是特殊字段?还有,如果特殊的prop1被声明为S

  • 问题内容: 我正在尝试为参数化的类重写方法。 我如何确保该对象与相同? 问题答案: 您可以通过保留对类型的引用来实现。但是,我认为, 相等性测试应该针对对象表示的值,而不是针对这些值表示的具体类型 。 一个典型的例子是Collections API。 返回。尽管它们具有完全不同的类型,但是它们表示相同的值,即“空集合”。 就个人而言,代表一个相同数据(例如)的两个s是否应该不相等,因为一个是类型,

  • 我是android编程的新手,我正在尝试通过改造连接到服务器并获取一些数据。我做了一个小例子来检查它是否会返回一些数据。首先,我不知道我是否编写了代码来做我想做的事情,其次,我得到了错误: "错误:(64,52)错误:不是抽象的,并且不重写回调中的抽象方法失败(RetrofitError)"和2个错误"错误:(67,13)错误:方法不重写或实现超类型中的方法" 这是我的代码。 }和我的改装界面 }