В классе Object этот метод реализован на уровне JVM. Сама виртуальная машина генерирует число хеш-кодов, основываясь на расположении объекта в памяти.
toString()
Этот метод позволяет получить текстовое описание любого объекта. Создавая новый класс, данный метод можно переопределить и возвращать более подробное описание. Для класса Object и его наследников, не переопределивших toString(), метод возвращает следующее выражение:
getClass().getName()+"@"+hashCode()
Метод getName() класса Class уже приводился в пример, а хэш-код еще дополнительно обрабатывается специальной функцией для представления в шестнадцатеричном формате.
Например:
print(new Object());
Результатом будет:
java.lang.Object@92d342
В результате этот метод позволяет по текстовому описанию понять, от какого класса был порожден объект и, благодаря хеш-коду, различать разные объекты, созданные от одного класса.
Именно этот метод вызывается при конвертации объекта в текст, когда он передается в качестве аргумента оператору конкатенации строк.
finalize()
Данный метод вызывается при уничтожении объекта автоматическим сборщиком мусора (garbage collector). В классе Object он ничего не делает, однако в классе-наследнике позволяет описать все действия, необходимые для корректного удаления объекта, такие как закрытие соединений с БД, сетевых соединений, снятие блокировок на файлы и т.д. В обычном режиме напрямую этот метод вызывать не нужно, он отработает автоматически. Если необходимо, можно обратиться к нему явным образом.
В методе finalize() нужно описывать только дополнительные действия, связанные с логикой работы программы. Все необходимое для удаления объекта JVM сделает сама.
Класс String
Как уже указывалось, класс String занимает в Java особое положение. Экземпляры только этого класса можно создавать без использования ключевого слова new. Каждый строковый литерал порождает экземпляр String, и это единственный литерал (кроме null ), имеющий объектный тип.
Затем значение любого типа может быть приведено к строке с помощью оператора конкатенации строк, который был рассмотрен для каждого типа, как примитивного, так и объектного.
Еще одним важным свойством данного класса является неизменяемость. Это означает, что, породив объект, содержащий некое значение-строку, мы уже не можем изменить данное значение – необходимо создать новый объект.
String s="a";
s="b";
Во второй строке переменная сменила свое значение, но только создав новый объект класса String.
Поскольку каждый строковый литерал порождает новый объект, что есть очень ресурсоемкая операция в Java, зачастую компилятор стремится оптимизировать эту работу.
Во-первых, если используется несколько литералов с одинаковым значением, для них будет создан один и тот же объект.
String s1 = "abc";
String s2 = "abc";
String s3 = "a"+"bc";
print(s1==s2);
print(s1==s3);
Результатом будет:
true
true
То есть в случае, когда строка конструируется из констант, известных уже на момент компиляции, оптимизатор также подставляет один и тот же объект.
Если же строка создается выражением, которое может быть вычислено только во время исполнения программы, то оно будет порождать новый объект:
String s1="abc";
String s2="ab";
print(s1==(s2+"c"));
Результатом будет false, так как компилятор не может предсказать результат сложения значения переменной с константой.
В классе String определен метод intern(), который возвращает один и тот же объект-строку для всех экземпляров, равных по значению. То есть если для ссылок s1 и s2 верно выражение s1.equals(s2), то верно и s1.intern()==s2.intern().
Разумеется, в классе переопределены методы equals() и hashCode(). Метод toString() также переопределен и возвращает он сам объект-строку, то есть для любой ссылки s типа String, не равной null, верно выражение s==s.toString().
Класс Class
Наконец, последний класс, который будет рассмотрен в этой лекции.
Класс Class является метаклассом для всех классов Java. Когда JVM загружает файл .class, который описывает некоторый тип, в памяти создается объект класса Class, который будет хранить это описание.
Например, если в программе есть строка
Point p=new Point(1,2);
то это означает, что в системе созданы следующие объекты:
1. объект типа Point, описывающий точку (1,2);
2. объект класса Class, описывающий класс Point;
3. объект класса Class, описывающий класс Object. Поскольку класс Point наследуется от Object, его описание также необходимо;
4. объект класса Class, описывающий класс Class. Это обычный Java-класс, который должен быть загружен по общим правилам.
Читать дальше