Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
V6049. Classes that define 'equals' met…
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Диагностика микро-оптимизаций (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Cтандарт MISRA
Стандарт AUTOSAR
Стандарт OWASP (C#)
Дополнительная информация
Оглавление

V6049. Classes that define 'equals' method must also define 'hashCode' method.

10 Май 2018

Анализатор обнаружил пользовательский тип, который переопределяет метод 'equals', но не переопределяет метод 'hashCode', и наоборот. Это может привести к неправильному функционированию пользовательского типа в сочетании с такими коллекциями как HashMap, HashSet и Hashtable, так как они активно используют 'hashCode' и 'equals' в своей работе.

Рассмотрим пример с использованием HashSet:

public class Employee {

  String name;
  int age;

  public Employee(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public String getName() { return name; }

  public void setName(String name) { this.name = name; }

  public int getAge() { return age; }

  public void setAge(int age) { this.age = age; }

  public String getFullInfo() {
    return this.name + " - " + String.valueOf(age);
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == this)
      return true;
    if (!(obj instanceof Employee))
      return false;
    Employee employee = (Employee) obj;
    return employee.getAge() == this.getAge()
            && employee.getName() == this.getName();
  }
} 

public static void main(String[] args)
{
  HashSet<Employee> employees = new HashSet<>();
  employees.add(new Employee("OLIVER", 25));
  employees.add(new Employee("MUHAMMAD", 54));
  employees.add(new Employee("OLIVER", 25));

  employees.forEach(arg -> System.out.println(arg.getFullInfo()));
}

В результате работы программы на консоль будет выведено:

OLIVER - 25
MUHAMMAD - 54
OLIVER - 25

Как видим, несмотря на то, что тип 'Employee' переопределяет метод 'equals', этого недостаточно. В ходе выполнения программы нам не удалось получить ожидаемого результата, и коллекция содержит повторяющиеся элементы. Для устранения этой проблемы в объявление типа 'Employee' необходимо добавить переопределение метода 'hashCode':

public class Employee {

...

@Override
public boolean equals(Object obj) {
  if (obj == this)
    return true;
  if (!(obj instanceof Employee))
    return false;
  Employee employee = (Employee) obj;
  return employee.getAge() == this.getAge()
          && employee.getName() == this.getName();
}

@Override
public int hashCode() {
    int result=17;
    result=31*result+age;
    result=31*result+(name!=null ? name.hashCode():0);
    return result;
}
} 

public static void main(String[] args)
{
  HashSet<Employee> employees = new HashSet<>();
  employees.add(new Employee("OLIVER", 25));
  employees.add(new Employee("MUHAMMAD", 54));
  employees.add(new Employee("OLIVER", 25));

  employees.forEach(arg -> System.out.println(arg.getFullInfo()));
}

Вновь выполним программу. В результате на консоль будет выведено:

MUHAMMAD - 54
OLIVER – 25

Мы получили корректный результат: коллекция содержит только уникальные элементы.

Данная диагностика классифицируется как:

  • CERT-MET09-J
Этот сайт использует куки и другие технологии, чтобы предоставить вам более персонализированный опыт. Продолжая просмотр страниц нашего веб-сайта, вы принимаете условия использования этих файлов. Если вы не хотите, чтобы ваши данные обрабатывались, пожалуйста, покиньте данный сайт. Подробнее →
Принять