Java 相同的两个对象的实现等于 class returns 在检查 getClass() 时为 false

Java equals implementation for two objects of the same class returns false when checking getClass()

我已经使用 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 - class com.utilities.domain.units.UnitSystem

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

units.UnitSystem - class com.utilities.domain.units.UnitSystem_$$_jvst6b1_19ed

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

此时相等性失败并且 equals returns 错误。

额外的_$$_jvst6b1_19ed是什么?它来自哪里?

据我了解,如果 classes 来自同一个 class 加载器,它们应该是相等的,它们就是。我在其他任何使用它的地方都没有遇到过这个实现的问题。为什么 getClass() 返回不同的东西?

正如@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;
  }

除非您实际上自己子class UnitSystem,否则不需要精确的class匹配,所以替换

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

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

你不能UnitSystem class final因为你希望Hibernate能够创建一个子class代理,所以你没有绝对保证 UnitSystem 不会被非 Hibernate 代码子class,但真的需要这样的绝对保证吗?