Java等于同一个类的两个对象的实现,在检查getClass()时返回false

时间:2018-10-25 15:47:12

标签: java equals hashcode

我已经使用NetBeans中的默认值为对象实现了hashCode()equals()

@Override
public int hashCode() {
    int hash = 5;
    hash = 37 * hash + this.unitSystemID;
    return hash;
}

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    LOGGER.debug(getClass().toString());
    LOGGER.debug(this.getClass().getClassLoader().toString());
    LOGGER.debug(obj.getClass().toString());
    LOGGER.debug(obj.getClass().getClassLoader().toString());
    if (getClass() != obj.getClass()) {
        return false;
    }
    final UnitSystem other = (UnitSystem) obj;
    if (this.unitSystemID != other.unitSystemID) {
        return false;
    }
    return true;
}

在记录检查点,我得到:

  

units.UnitSystem-类   com.utilities.domain.units.UnitSystem

     

units.UnitSystem-   org.springframework.boot.devtools.restart.classloader.RestartClassLoader@42d353e2

     

units.UnitSystem-类   com.utilities.domain.units.UnitSystem _ $$ _ jvst6b1_19ed

     

units.UnitSystem-   org.springframework.boot.devtools.restart.classloader.RestartClassLoader@42d353e2

这时相等失败,并且equals返回false。

多余的_$$_jvst6b1_19ed是什么?它来自哪里?

据我了解,如果这些类来自相同的类加载器,则它们应该相等。在其他任何我使用过的地方,这个实现都没有问题。为什么getClass()返回不同的内容?

2 个答案:

答案 0 :(得分:2)

除非您自己真正地继承UnitSystem的子类,否则不需要精确的类匹配,因此请替换

if (getClass() != obj.getClass()) {
    return false;
}

使用

if (! (obj instanceof UnitSystem)) {
    return false;
}

您不能使UnitSystemfinal属于Hibernate,因为它希望Hibernate能够创建子类代理,因此您不能绝对保证不会UnitSystem被由非Hibernate代码子类化,但是真的需要这样的绝对保证吗?

答案 1 :(得分:0)

正如@Andreas在评论中所说,通常是在通过延迟加载获取对象后才会发生。要获得初始对象,您应该先取消代理。这是Hibernate

的解包器示例
 @SuppressWarnings("unchecked")
  public static <T> T initializeAndUnproxy(T entity) {
    if (entity == null) {
      throw new InternalServerException("Entity passed for initialization is null");
    }

    T unproxy = entity;
    Hibernate.initialize(entity);
    if (isProxy(entity)) {
      unproxy = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
    }
    return unproxy;
  }

  public static <T> boolean isProxy(T entity) {
    return entity instanceof HibernateProxy;
  }