Рубрики
Без рубрики

Почему хэш-код объекта java не согласован на разных хостах

Предыстория Недавно один из наших клиентов API жаловался, что etag нашего API не является wo… Помеченный java, хэш-код.

Фон

Недавно один из наших клиентов API жаловался на то, что etag нашего API работает некорректно. Итак, я начал проверять, в чем дело. И что я обнаружил, так это то, что etag на разных хостах не соответствует друг другу. Итак, etag – это шестнадцатеричная строка хэш-кода объекта java. Поначалу я понятия не имел, в чем дело. Поскольку другие API работают, только один из API не работает. Итак, я написал простой тестовый код, который печатает каждое поле объекта. Наконец, я обнаружил, что хэш-код java enum отличается на разных хостах. Так почему же?

Почему?

Я только что погуглил вопрос и нашел этот post . Это точно такая же проблема, как и у меня.

Давайте взглянем на определение java enum hashcode в официальном документе.

public final int hashCode()
Returns a hash code for this enum constant.
Overrides:
hashCode in class Object
Returns:
a hash code for this enum constant.

Видите, в чем проблема? Здесь говорится, что он возвращает хэш-код для этой константы перечисления. Константа перечисления – это объект перечисления, и она постоянна. Таким образом, это согласуется с JVM. Но каждая JVM должна иметь свою собственную константу перечисления. Это объясняет мой вопрос в самом начале. Перечисления на разных JVM будут иметь разные хэш-коды.

Как решить эту проблему?

Итак, мы знаем, что происходит. Но, как это решить. Как вы можете видеть, функция enum hashcode является методом final . Итак, это означает, что мы не можем его переопределить.

Это говорит нам о том, что единственный способ переопределить хэш-код – это место, где мы используем объект enum. Давайте приведем пример.

class TestDAO {
  private String test1;
  private Type type;

  enum Type {
    APPLE,
    ORANGE
  }
}

Давайте переопределим метод hashcode в Test DAO.

class TestDAO {
  private String id;
  private Type type;

  @Override
  public hashCode(){
    Objects.hashCode(id, type.name());
  }

  @Override
  public equals(){
    ...
  }

  enum Type {
    APPLE,
    ORANGE
  }
}

Обратите внимание, разница в том, что мы используем type.name () вместо самого типа. Это решает проблему. Не идеально, но работает.

Ссылка: https://madhead.me/posts/enums-fuckup/ https://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#hashCode () https://madhead.me/posts/enums-fuckup/

Оригинал: “https://dev.to/jiayanguo/why-isn-t-the-hashcode-of-a-java-object-consistent-on-different-hosts-me9”