Шаг 35.
Язык программирования Java.
Глобальный суперкласс Object

На этом шаге мы поговорим про глобальный суперкласс Object

Класс Object является исходным предшественником всех остальных классов, поэтому каждый класс в Java расширяет класс Object. Если суперкласс явно не указан, им считается класс Object. Поэтому очень важно знать, какими средствами обладает сам класс Object.

Переменную типа Object можно использовать в качестве ссылки на объект любого типа следующим образом:

Object obj = new Employee(...);

Разумеется, переменная этого класса полезна лишь как средство для хранения значений произвольного типа. Чтобы сделать с этим значением что-то конкретное, нужно знать его исходный тип, а затем выполнить приведение типов. В Java объектами не являются только примитивные типы: числа, символы и логические значения.

В методе equals() из класса Object проверяется, равнозначны ли два объекта. А поскольку метод equals() реализован в классе Object, то в нем определяется только следующее: ссылаются ли переменные на один и тот же объект. Но в ряде случаев равнозначными должны считаться объекты одного типа, находящихся в одном и том же состоянии.

Спецификация Java требует, чтобы метод equals() обладал следующими характеристиками:

  1. Рефлексивность. При вызове x.equals(x) по любой ненулевой ссылке x должно возвращаться логическое значение true.
  2. Симметричность. При вызове x.equals(y) по любым ссылка x и y должно возвращаться логическое значение true, тогда и только тогда, когда при вызове y.equals(x) возвращается логическое значение true.
  3. Транзитивность. Если при вызовах x.equals(y) и y.equals(z) по любым ссылкам x, y и z возвращается логическое значение true, то и при вызове x.equals(z) возвращается логическое значение true.
  4. Согласованность. Если объекты, на которые делаются ссылки x и y, не изменяются, то при повторном вызове x.equals(y) должно возвращаться то же самое значение.
  5. При вызове x.equals(null) по любой непустой ссылке x должно возвращаться логическое значение false.

Хеш-код - это целое число, генерируемое на основе конктреного объекта. Хеш-код можно рассматривать как некоторый шифр: если x и y - разные объекты, то с большей степенью вероятности должны различаться их хеш-коды. В Java узнать хеш-код объекта можно с помошью метода hashCode().

Если вы переопределили метод equals(), то вам следует переопреледить и метод hashCode(). Метод hashCode() должен возвращать целочисленное значение, которое может быть отрицательным. Для того чтобы хеш-коды разных объектов отличались, достаточно объединить хеш-коды полей экземпляра. Ниже приведен пример реализации метода hashCode() в класса Employee:

class Employee {
	...
	public int hashCode() {
		return 7 * name.hashCode() +
		       11 * new Double(salary).hashCode() +
		       13 * hireDay.hashCode();
	}
	...
}

Начиная с версии Java 7 были внесены два усовершенствования. Во-первых, можно воспользоваться методом Objects.hashCode(), безопасно обрабатывающий пустые значения. Во-вторых, можно вызвать метод Objects.hash(), если требуется объединить несколько хеш-значений. Перепишем метод hashCode() класса Employee следующим образом:

public int hashCode() {
	return Objects.hash(name, salary, hireDay);
}

Методы equals() и hashCode() должны быть совместимы: если при вызове x.equals(y) возвращается логическое значение true, то и результаты вызовов x.hashCode() и y.hashCode() также должны совпадать.

На следующем шаге мы поговорим про приведение типов.

Предыдущий шаг Содержание Следующий шаг