Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

256
Views
Java @Override equals(): Cuando this.getClass() != o.getClass() falla pero no debería

Tengo este @Override for equals() en mi clase MyClass :

 @Entity( name = "MyClass" ) @Table( name = "my_class" ) 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 ); } ... }

Bastante estándar. De hecho, sigue las mejores prácticas de Java.
Más tarde en la vida tengo esto en otra clase de subpaquete (mi clase de controlador):

 ... package com.abapi.controllers; ... import com.abjpa.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 ); ...

Mi problema es que .equals() siempre falla aquí:

 if ( o == null || this.getClass() != o.getClass() )

porque java dice que this.getClass() y o.getClass() NO son iguales. Cuando depuro el código (en Intellij IDEA 2022.1 UE) veo esto:

this.getClass() = MiClase@13706

pero

o.getClass = com.abjpa.models.MyClass@8f7462

¡Pero son de la misma clase! Casi todos los libros, tutoriales, blogs, Intellij IDEA, etc. de Java demuestran el .equals() de esta manera. Probé esto en Ubuntu 20.04.4 LTS java-14-openjdk-amd64 y java-17-openjdk-amd64 con los mismos resultados.

¿Qué estoy haciendo mal?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

myObject2 es una instancia de una clase proxy, generada en tiempo de ejecución por Hibernate usando Byte Buddy . El proxy generado intercepta todas las invocaciones de métodos, por eso getClass() devuelve resultados diferentes.

Como alternativa a getClass() , el uso de instanceof podría ser otro enfoque:

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

Sin embargo, tenga en cuenta que instanceof tiene sus inconvenientes . Viola el principio de simetría.

En primer lugar, no debe comparar estos objetos, ya que un objeto nuevo debe ser diferente de uno administrado por Hibernate que tiene un estado persistente.

over 4 years ago · Santiago Trujillo Report

0

Utilizo estas implementaciones estándar de hashcode y equals para entidades JPA (como se describe aquí ):

 @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(); }
over 4 years ago · Santiago Trujillo Report

0

No está utilizando una mejor práctica. Cambie sus iguales para que sean algo como lo siguiente (verificación nula primero, luego la misma verificación, luego verificación de clase):

 public boolean equals(Object obj) { if (obj == null) { return false; } if (obj == this) { return true; } if (obj.getClass() != getClass()) { return false; } ... do the actual comparison here }

Nota: el código anterior es una paráfrasis de Apache EqualsBuilder

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!