object java что это такое
Класс Object
В Java есть специальный суперкласс Object и все классы являются его подклассами. Поэтому ссылочная переменная класса Object может ссылаться на объект любого другого класса. Так как массивы являются тоже классами, то переменная класса Object может ссылаться и на любой массив.
В таком виде объект обычно не используют. Чтобы с объектом что-то сделать, нужно выполнить приведение типов.
У класса есть несколько важных методов.
Методы getClass(), notify(), notifyAll(), wait() являются финальными и их нельзя переопределять.
Метод hashCode()
Для вычисления хеш-кода в классе String применяется следующий алгоритм.
У любого объекта имется хеш-код, определяемый по умолчанию, который вычисляется по адресу памяти, занимаемой объектом.
Значение хеш-кода возвращает целочисленное значение, в том числ и отрицательное.
Если в вашем классе переопределяется метод equals(), то следует переопределить и метод hashCode().
Метод toString()
Очень важный метод, возвращающий значение объекта в виде символьной строки.
Очень часто при использовании метода toString() для получения описания объекта можно получить набор бессмысленных символов, например, [I@421199e8. На самом деле в них есть смысл, доступный специалистом. Он сразу может сказать, что мы имеем дело с одномерным массивом (одна квадратная скобка), который имеет тип int (символ I). Остальные символы тоже что-то означают, но вам знать это не обязательно.
Если же вам нужно научное объяснение, то метод работает по следующему алгоритму (из документации).
Обычно принято переопределять метод, чтобы он выводил результат в читаемом виде.
Объекты в Java
1. Объекты
Все в Java является объектом.
Вернее, очень мало чего в Java объектом не является. Например, примитивные типы. Но это скорее редкое исключение, чем правило.
Что же такое объект?
Объект — это сгруппированные вместе данные и методы для того, чтобы эти данные обрабатывать. Когда мы говорим о данных, имеем в виду переменные, конечно.
Про переменные объекта говорят, что это «данные объекта» или «состояние объекта».
Про методы объекта говорят: это «поведение объекта». Состояние объекта (переменные объекта) принято менять только с помощью методов того же объекта. Менять переменные объекта напрямую (не через методы объекта) считается дурным тоном.
У каждого объекта, как и у каждой переменной, есть тип. Этот тип определяется один раз при создании объекта и поменять его в дальнейшем нельзя. Типом объекта считается его класс.
У каждого объекта есть собственная копия переменных класса (полей класса). Если в классе была объявлена нестатическая переменная int a, и ваша программа во время работы создала 10 объектов этого класса, теперь в каждом объекте есть собственная переменная int a.
Взаимодействие с объектом
Самый удобный способ работы с объектом — сохранить ссылку на объект в переменную, и потом вызывать методы у этой переменной. Выглядит это для вас знакомо:
Где переменная — это переменная, которая хранит в себе ссылку на объект, а метод — это метод класса объекта.
Если вы хотите обратиться к полю (переменной) объекта, то тоже нужно использовать оператор точка :
Где переменная — это переменная, которая хранит в себе ссылку на объект, а поле — это переменная класса (поле объекта).
2. Оператор new
Где Класс — это имя класса для объявления переменной и имя класса создаваемого объекта. Переменная — это переменная, в которую сохраняется ссылка на созданный объект. А параметры — это параметры метода создания объекта.
Какие именно могут быть параметры у объекта, решают программисты, которые пишут класс объекта.
Вы уже создавали объекты ранее, и даже пользовались именно этой конструкцией. Надеюсь, вы не забыли?
Примеры создания объектов:
Код | Описание |
---|---|
Создает объект типа String | |
Создает объект типа Scanner | |
Создает объект типа int[] : контейнер на 10 элементов типа int |
Объекты, классы и типы в Java
Java – это объектно-ориентированный язык программирования. Java состоит из основополагающих компонентов:
Рассмотрим компоненты – классы и объекты Java.
Объекты в Java
Разберём детально, что представляет собой объект в Java. Если оглянуться вокруг, мы найдём много объектов вокруг нас: автомобили, собаки, люди. Все они имеют состояние и поведение.
Если мы рассмотрим автомобиль, то его состояние – марка, цвет, стоимость и поведение – передвигается по дорогам, требует ремонта.
Если вы сравниваете виртуальный объект с настоящим объектом, они имеют очень похожие характеристики.
Виртуальные объекты также имеют состояние и поведение. Состояние виртуального объекта сохраняется в полях, а поведение отображается с помощью методов.
Получается, при разработке программного обеспечения методы работают с внутренним состоянием объекта, а связь между объектами осуществляется с помощью методов.
Описание классов в Java
Класс – это компонент языка Java, из которого создаются отдельные объекты.
Ниже приведен образец класса.
Класс может содержать в себе типы переменных:
Класс может иметь бесконечно много методов для доступа к значению различных видов методов. В приведенном выше примере barking(), hungry() и sleep() являются методами.
Ниже приведены некоторые важные темы, которые необходимо знать при изучении классов.
Описание конструкторов
У каждого класса есть конструктор. Если мы явно не пишем конструктор для класса, компилятор Java создает конструктор по умолчанию для этого класса.
Каждый раз, когда создается новый объект, будет вызываться как минимум один конструктор. Основное правило конструкторов заключается в том, что они должны иметь то же имя, что и класс. Класс может иметь более одного конструктора.
Ниже приведен пример конструктора:
Java также поддерживает Singleton Classes(Одноэлементные), где вы сможете создать только один экземпляр класса.
Построение объекта
В основном, объект создается из класса.
Есть три шага при создании объекта из класса:
Ниже приведен пример создания объекта
Если мы скомпилируем и запустим вышеуказанную программу, то она даст следующий результат:
Введенное имя: Томми
Доступ к переменным и методам экземпляра
Переменные и методы экземпляра доступны через созданные объекты. Чтобы получить доступ к переменной экземпляра, следующий полный путь:
В этом примере объясняется, как получить доступ к переменным экземпляра и методам класса.
Если мы скомпилируем и запустим вышеуказанную программу, то она даст следующий результат:
Имя выбрано: Томми
Возраст щенка: 2
Значение переменной: 2
Правила объявления исходного файла
Теперь рассмотрим правила объявления исходного файла.
У классов есть несколько уровней доступа, и есть разные типы классов; абстрактные классы, финальные классы и т. д.
Помимо вышеупомянутых типов классов, в Java также есть некоторые специальные классы, называемые классами Inner и классами Anonymous(анонимные).
Проще говоря, это способ классификации классов и интерфейсов. При разработке приложений на Java будут написаны сотни классов и интерфейсов, поэтому классификация этих классов является обязательной, а также значительно облегчает жизнь.
Для нашего примера мы создадим два класса. Это Employee и EmployeeTest.
Сначала откройте блокнот и добавьте следующий код. Помните, что это класс Employee, а этот класс является публичным. Теперь сохраните этот исходный файл с именем Employee.java.
Класс Employee имеет четыре переменных экземпляра – имя, возраст, назначение и зарплата. У класса есть один явно определенный конструктор, который принимает параметр.
Чтобы запустить класс Employee, должен быть метод main и объекты должны быть созданы. Необходимо создавать отдельный класс для этих задач.
Ниже воспроизведён класс EmployeeTest, создающий два класса Employee и обращается к методам для каждого объекта, чтобы назначить значения для каждой переменной.
Сохраните следующий код в файле EmployeeTest.java.
Теперь скомпилируем оба класса и запустим EmployeeTest:
Классы и объекты в Java
Java — объектно-ориентированный язык, а значит, программы состоят из объектов и классов. Разбираемся, что это такое.
Если в коде программы на объектно-ориентированном языке нужно отразить сущность каких-то объектов, используется понятие класса.
Возьмём пример из реального мира. У многих, вероятно, есть кошка, собака или хомячок, а у кого-то могут быть даже коровы, гуси, овцы. Любое из этих существ (объектов) можно охарактеризовать словами «домашнее животное» и у каждого есть свой набор атрибутов: вес, кличка, свой тип (корова, гусь, овца, собака и так далее). А ещё они, очевидно, могут есть и передвигаться.
Класс — это шаблонная конструкция, которая позволяет описать в программе объект, его свойства (атрибуты или поля класса) и поведение (методы класса).
Каждый класс имеет своё имя, чтобы в будущем к нему можно было обратиться. Чтобы создать класс на Java, необходимо написать слово class, дать ему название и поставить фигурные скобки:
Имя класса в нашем примере — Pet.
Java-разработчик, преподаёт в Skillbox, осваивает машинное обучение.
Параметры класса
Мы можем создавать поля класса, каждое из которых имеет свой тип.
Поле класса — это переменная, которая описывает какое-либо из свойств данного класса.
Для наших домашних питомцев и полями класса будут вес, кличка и принадлежность к определённому типу (коровы, гуси, собаки и так далее). Очевидно, что здесь вес — это числовая переменная, а кличка и тип — строки символов. Тогда мы можем написать:
Переменные weight, name и type — поля нашего класса Pet, то есть свойства, которые описывают объект этого класса. Таких полей может быть сколько угодно, каждое имеет свой тип, как обычная переменная.
Мы уже пару раз упомянули словосочетание «объект класса». Так говорят, потому что любой объект является экземпляром какого-либо класса. Здесь действует простая аналогия: класс — это как бы чертёж, который описывает объект, его устройство, а объект — реализация чертежа, его материальное воплощение.
Давайте запрограммируем первый объект класса Pet. Пусть это будет кот ( type) с кличкой ( name) Барсик и весом ( weight) 10 (измерение в килограммах).
Сперва необходимо создать переменную типа Pet:
Наш объект pet выглядит как обычная переменная, но в качестве типа указан класс Pet, и в данный момент в нём ничего нет. Инициализируем объект — воспользуемся такой синтаксической конструкцией:
Мы ставим знак равно, пишем ключевое слово new, имя нашего класса и круглые скобки. Принято говорить, что здесь мы вызываем конструктор класса Pet. Пока просто запомним это — о конструкторах и о том, как их использовать, будет рассказано в отдельной статье.
Теперь у нас появилась переменная pet типа Pet, в которой содержится объект класса Pet. Ранее в этом классе мы объявили поля, к которым можно обратиться и занести в них значения.
Чтобы получить доступ к какому-либо полю нашего класса Pet, нужно специальным образом обратиться к переменной pet — поставить точку и вызвать необходимое поле. Например, вот так:
Теперь во всех трёх полях есть по значению, а мы можем получить их из программы, если потребуется, — например, распечатать в консоль:
Изменить значение в любом из полей класса также несложно. Пусть наш кот Барсик слегка потолстеет — добавим к его весу 1 кг:
Как видим, мы просто изменили вес в поле weight, а при выводе получили уже другое значение.
Методы класса
В начале статьи я упомянул, что наши домашние животные могут перемещаться и есть. В отличие от параметров вроде веса и клички, это уже не свойства объекта, а его функции. В классе эти функции обозначают как методы.
Метод класса — это блок кода, состоящий из ряда инструкций, который можно вызывать по его имени. Он обязательно содержит возвращаемый тип, название, аргументы и тело метода.
Синтаксис метода в Java:
Строка возвращаемыйТип показывает, какого типа данные вернёт метод. Например, если в качестве возвращаемого типа мы поставим тип String, то метод должен будет вернуть строку, а если int — целое число.
Чтобы вернуть значение из метода, используется специальное слово return. Если мы хотим, чтобы метод ничего не возвращал, то вместо возвращаемого типа нужно использовать специальное слово void.
Аргументы — то, что нужно передать в метод при его вызове. Мы можем указать сколько угодно параметров через запятую либо не указывать ни одного.
Для примера напишем простейший метод с именем sum (пока что не в нашем классе Pet), который складывает два переданных числа и возвращает их результат:
Возвращаемый тип метода int, он указан перед именем sum. Далее идут два аргумента a и b, у обоих также указан тип int. Важно помнить, что возвращаемый тип и тип переменных не обязательно должны совпадать.
Аргументы метода работают как обычные переменные — за пределами метода к ним никак нельзя получить доступ. Внутри метода мы складываем значения из переменных a и b, записываем полученное значение в переменную c. После этого мы возвращаем значение переменной c — только оно доступно вне метода.
Мы передали в метод sum два значения 1 и 2, а на выходе получили результат их сложения 3. Также можно создать метод, который принимает значение типа String, а возвращает длину этой строки:
В этом случае у нас возвращаемый типа int, а параметр str — типа String.
Попробуем использовать этот метод:
Также мы можем создать метод, который ничего не возвращает, а просто печатает переданное слово в консоль:
Либо метод, который ничего не принимает на вход, а просто печатает «Привет!»:
В методах, которые ничего не возвращают, слово return можно опустить.
Обратите внимание, что return полностью прекращает выполнение метода:
Теперь попробуем вызвать этот метод, передав в него число 3:
В этом случае мы ничего не увидим в консоли, так как 3 меньше 5, а значит, отработает блок if и произойдёт выход из метода с помощью слова return.
Но если передадим 6, увидим нашу надпись «Привет!»:
Методы в классах
Теперь, когда мы разобрались, что такое методы, давайте создадим два метода — eat и run — в классе Pet.
Пусть первый из них принимает на вход параметр типа int и увеличивает на это значение поле weight (сколько скушал питомец, на столько и потолстел). А после этого печатает в консоль «Я поел» и возвращает новый вес.
Второй из методов run пусть уменьшает вес на 1, но только если он больше 5, и печатает в консоль: «Я бегу». Иначе, если вес меньше или равен 5: «Я не могу бежать».
Теперь мы можем вызвать эти методы у объектов класса Pet. Чтобы это сделать, нужно обратиться к объекту, поставить точку и таким способом вызвать необходимый метод.
Иногда в каком-то методе требуется создать параметр, у которого имя совпадает с именем поля класса. В таких случаях, чтобы обратиться внутри метода именно к полю класса, а не к параметру нашего метода, используется ключевое слово this.
Для иллюстрации этого создадим метод, setName, который будет устанавливать переданное значение в поле name, а затем сообщать в консоль, что нашего питомца теперь зовут по-другому.
В результате с помощью this.name мы обращаемся к полю name и заносим в него значение из параметра метода name.
Также мы можем вызывать один метод вслед за другим. Давайте сделаем так, чтобы метод eat возвращал текущее животное с помощью this.
Теперь мы можем написать так:
Здесь мы дважды вызываем метод eat у одного и того же объекта класса (кота), а следом за ним вызываем метод run. И все эти вызовы делаются последовательно в одной строке, через точку.
Статические поля и методы
С помощью специального слова static мы можем создать статические поля и методы. Эти поля и методы описывают уже не объект класса, а сам класс. То есть они вызываются по имени класса, а их значение — общее для всех объектов данного класса.
Например, мы хотим посчитать, сколько еды съели все домашние животные. Введём поле amountOfAllFood типа int и добавим к нему слово static. А также введём нестатическое поле amountOfFood. Изменять данные поля мы будем в методе eat.
Теперь попробуем создать двух животных, и пусть каждое из них поест.
Как видите, к полю amountOfAllFood мы обращаемся уже не через объект, а по имени класса, и в этом поле хранится общее количество съеденной еды. Зато в поле amountOfFood у каждого животного — именно своё количество съеденной еды.
Мы можем обратиться к полю amountOfAllFood и через объект — результат будет тот же. Но принято обращаться именно через имя класса:
Как вы могли заметить, в нашем примере постоянно дублируется код с выводом информации об объекте. Давайте вынесем его в отдельный метод в классе Pet:
Теперь нам достаточно лишь обратиться к методу printInfo через объект, о котором мы хотим получить информацию.
Но у нас есть ещё строка с выводом общего количества еды. Можем ли мы поместить её в метод printInfo? Да, оказывается, можем:
Всё хорошо, но теперь при каждом вызове printInfo у нас будет печататься информация об общем количестве еды. Чтобы этого избежать, лучше вынести строку в отдельный статический метод:
У статического метода printStaticInfo также нет никаких отличий от обычного метода, но он относится к классу, а не к объекту данного класса. Вызываем его через обращение к классу:
Важно заметить, что из метода printStaticInfo мы можем обратиться только к статическим полям. Это происходит потому, что нестатические поля существуют в рамках конкретного объекта класса, а статический метод — в рамках всего класса.
Но можно добавить параметр типа Pet в данный метод — тогда у этого параметра мы будем вызывать необходимые поля. Например, так:
Подытожим
Важные примечания
Работать с классами и объектами в языке Java несложно, но есть несколько важных правил-примечаний, на которые нужно обратить внимание:
Java Blog
Методы класса Object в Java
Класс Object является корнем иерархии классов. У каждого класса есть Object как суперкласс. Все объекты, включая массивы, реализуют методы этого класса.
Методы класса Object
Метод getClass()
Метод getClass() возвращает:
Объект Class, представляющий класс времени исполнения (runtime class) этого объекта.
Метод hashCode
Возвращает значение хэш-кода для объекта. Этот метод поддерживается для использования хэш-таблиц, таких как те, что предоставляются HashMap.
Основной контракт метода hashCode:
Насколько это практически целесообразно, метод hashCode, определенный классом Object, возвращает разные целые числа для разных объектов. (Обычно это реализуется путем преобразования внутреннего адреса объекта в целое число, но этот метод реализации не требуется языком программирования Java.)
Метод hashCode возвращает:
Целочисленное (int) значение хэш-кода для этого объекта.
Метод equals
Указывает, равен ли какой-либо другой объект этому объекту.
Метод equals реализует отношение эквивалентности для ненулевых ссылок на объекты:
Метод equals для класса Object реализует максимально различающее возможное отношение эквивалентности на объектах; то есть для любых ненулевых ссылочных значений x и y этот метод возвращает true только тогда, когда x и y ссылаются на один и тот же объект (x == y имеет значение true).
Обратите внимание, что обычно необходимо переопределять метод hashCode всякий раз, когда метод equals переопределяется, чтобы поддерживать общий контракт для метода hashCode, в котором говорится, что равные объекты должны иметь одинаковые хэш-коды.
Метод equals возвращает:
Значение true, если этот объект совпадает с аргументом obj; false в противном случае.
Метод clone
Создает и возвращает копию этого объекта. Точное значение «копия» может зависеть от класса объекта. Общее намерение состоит в том, что для любого объекта x, выражение:
будет верно, и это выражение:
будет верно, но это не абсолютные требования. Хотя обычно это так:
будет верно, это не является абсолютным требованием.
По соглашению, возвращаемый объект должен быть получен путем вызова super.clone. Если класс и все его суперклассы (кроме Object) подчиняются этому соглашению, это будет иметь место в том случае, если x.clone().getClass() == x.getClass().
По соглашению объект, возвращаемый этим методом, должен быть независимым от этого объекта (который клонируется). Для достижения этой независимости может потребоваться изменить одно или несколько полей объекта, возвращаемого super.clone, перед его возвратом. Как правило, это означает копирование любых изменяемых объектов, которые составляют внутреннюю «глубокую структуру» клонируемого объекта, и замену ссылок на эти объекты ссылками на копии. Если класс содержит только примитивные поля или ссылки на неизменяемые объекты, то обычно бывает так, что нет необходимости изменять поля в объекте, возвращаемом super.clone.
Класс Object сам по себе не реализует интерфейс Cloneable, поэтому вызов метода clone для объекта, класс которого Object, приведет к возникновению исключения во время выполнения.
Метод clone возвращает:
клон этого экземпляра.
Метод clone выбрасывает:
Метод toString
Возвращает строковое представление объекта. В общем случае метод toString возвращает строку, которая является «текстовым представлением» этого объекта. Результатом должно быть краткое, но информативное представление, которое легко читается человеком. Рекомендуется, чтобы все подклассы переопределяли этот метод.
Метод toString для класса Object возвращает строку, состоящую из имени класса, экземпляром которого является объект, символа знака «@» и шестнадцатеричного представления без знака хэш-кода объекта. Другими словами, этот метод возвращает строку, равную значению:
Метод toString возвращает:
строковое представление объекта.
Метод notify
Пробуждает один поток, который ожидает на мониторе этого объекта. Если какие-либо потоки ожидают этого объекта, один из них выбирается для пробуждения. Выбор является произвольным и происходит на усмотрение реализации. Поток ожидает на мониторе объекта, вызывая один из методов wait.
Пробужденный поток не сможет продолжить работу, пока текущий поток не снимет блокировку этого объекта. Пробужденный поток будет конкурировать обычным образом с любыми другими потоками, которые могут активно конкурировать за синхронизацию на этом объекте; например, пробужденный поток не имеет надежных привилегий или недостатков в качестве следующего потока для блокировки этого объекта.
Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта. Поток становится владельцем монитора объекта одним из трех способов:
Только один поток одновременно может владеть монитором объекта.
Метод notifyAll
Пробуждает все потоки, которые ожидают на мониторе этого объекта. Поток ожидает на мониторе объекта, вызывая один из методов wait.
Пробужденные потоки не смогут продолжить работу, пока текущий поток не снимет блокировку этого объекта. Пробужденные потоки будут конкурировать обычным образом с любыми другими потоками, которые могут активно конкурировать за синхронизацию на этом объекте; например, пробужденные потоки не имеют надежных привилегий или недостатков в качестве следующего потока для блокировки этого объекта.
Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта.
Метод wait с аргументом timeout
Заставляет текущий поток ждать, пока другой поток не вызовет метод notify() или метод notifyAll() для этого объекта, или пока не истечет указанное количество времени.
Текущий поток должен владеть монитором этого объекта.
Этот метод заставляет текущий поток (назовем его T) поместить себя в набор ожидания для этого объекта, а затем отказаться от любых заявлений на синхронизацию этого объекта. Поток T становится отключенным для целей планирования потоков и остается бездействующим, пока не произойдет одно из четырех:
Затем поток T удаляется из набора ожидания для этого объекта и снова включается для планирования потока. Затем он конкурирует обычным образом с другими потоками за право синхронизации на объекте; как только он получил контроль над объектом, все его заявки на синхронизацию с объектом восстанавливаются до состояния quo ante, то есть ситуации на момент вызова метода wait. Затем поток T возвращается из вызова метода ожидания. Таким образом, при возврате из метода ожидания состояние синхронизации объекта и потока Т точно такое же, как и при вызове метода ожидания.
Поток также может просыпаться без уведомления, прерывания или истечения тайм-аута, так называемое ложное пробуждение (spurious wakeup). Хотя это редко случается на практике, приложения должны защищаться от него, проверяя условие, которое должно было вызвать пробуждение потока, и продолжая ждать, если условие не выполняется. Другими словами, ожидания всегда должны происходить в циклах, например:
Если текущий поток прерывается каким-либо потоком до или во время ожидания, генерируется исключение InterruptedException. Это исключение не выдается, пока состояние блокировки этого объекта не будет восстановлено, как описано выше.
Обратите внимание, что метод wait, поскольку он помещает текущий поток в набор ожидания для этого объекта, разблокирует только этот объект; любые другие объекты, по которым текущий поток может быть синхронизирован, остаются заблокированными, пока поток ожидает.
Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта.
Метод wait с аргументами timeout и nanos
Заставляет текущий поток ждать, пока другой поток не вызовет метод notify() или метод notifyAll() для этого объекта, или какой-либо другой поток прервет текущий поток, или пока не истекло определенное количество реального времени.
Этот метод аналогичен методу wait с одним аргументом, но он позволяет лучше контролировать время ожидания уведомления перед тем, как отказаться. Количество реального времени, измеряемое в наносекундах, определяется как:
Во всех других отношениях этот метод делает то же самое, что и метод wait(long) с одним аргументом. В частности, wait(0, 0) означает то же самое, что и wait(0).
Текущий поток должен владеть монитором этого объекта. Поток освобождает владельца этого монитора и ожидает, пока не произойдет одно из следующих двух условий:
Затем поток ожидает, пока не получит право собственности на монитор, и возобновит выполнение.
Как и в версии с одним аргументом, возможны прерывания и ложные пробуждения, и этот метод всегда должен использоваться в цикле:
Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта.
Метод wait без аргументов
Заставляет текущий поток ждать, пока другой поток не вызовет метод notify() или метод notifyAll() для этого объекта. Другими словами, этот метод ведет себя точно так же, как если бы он просто выполнял вызов wait(0).
Текущий поток должен владеть монитором этого объекта. Поток освобождает владельца этого монитора и ожидает, пока другой поток не уведомит потоки, ожидающие на мониторе этого объекта, чтобы он проснулся либо посредством вызова метода notify, либо метода notifyAll. Затем поток ожидает, пока не получит право собственности на монитор, и возобновит выполнение.
Как и в версии с одним аргументом, возможны прерывания и ложные пробуждения, и этот метод всегда должен использоваться в цикле:
Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта.
Метод finalize
Вызывается сборщиком мусора на объекте, когда сборщик мусора определяет, что больше нет ссылок на объект. Подкласс переопределяет метод finalize для удаления системных ресурсов или для другой очистки.
Метод finalize класса Object не выполняет никаких специальных действий; он просто выполняет возврат. Подклассы Object могут переопределить это поведение.
Язык программирования Java не гарантирует, какой поток вызовет метод finalize для любого данного объекта. Однако гарантируется, что поток, который вызывает finalize, не будет удерживать видимые пользователем блокировки синхронизации, когда вызывается finalize. Если с помощью метода finalize генерируется неперехваченное исключение, оно игнорируется, и финализация этого объекта завершается.
После того, как метод finalize был вызван для объекта, никакие дальнейшие действия не предпринимаются, пока виртуальная машина Java снова не определит, что больше нет никаких средств, с помощью которых этот объект мог бы быть доступен любому потоку, который еще не жив, включая возможные действия другими объектами или классами, которые готовы к финализации, после чего объект может быть удален.
Метод finalize никогда не вызывается виртуальной машиной Java более одного раза для любого данного объекта.
Любое исключение, выброшенное методом finalize, приводит к остановке завершения этого объекта, но в противном случае игнорируется.