Перейти к содержимому

Getclass java что это

  • автор:

А знаете ли Вы, что возвращает .getClass()?

Я думаю, почти любого Java разработчика когда-то спрашивали на собеседовании: «Какие есть методы у класса Object?»
Меня, по крайней мере, спрашивали неоднократно. И, если в первый раз это было неожиданностью (кажется, забыл про clone), то потом я был уверен, что уж методы Object’а-то я знаю;)

И каково же было мое удивление, когда спустя несколько лет разработки я наткнулся на собственное незнание сигнатуры метода getClass()

Под катом пара слов про Class, .class, .getClass и, собственно, сюрприз, на который я наткнулся.

Итак, у нас есть класс А и объект этого класса a:

public class A < >. A a = new A(); 
0. A.class vs a.getClass()

Начнем с простого. При вызове getClass() может отработать полиморфизм, и результатом будет класс-потомок.

public class B extends A < < . A a1 = new B(); a1.getClass(); // то же самое, что B.class 

Скрытый текст

Тут была ложь, на которую мне указали в комментариях. class — это не статическое поле, коим может показаться (и даже не нативное-псевдо-статическое поле, как думал я), а особая конструкция языка. И, в отличие от статического поля, обратиться к нему через объект нельзя!

a.class; // Compile error! Unknown class: "a" 

Но это так, цветочки. Идем дальше.

1. А что такое этот ваш Class?

A.class — объект класса Class. Смотрим в Class.java:

public final class Class implements . 

Это дженерик. Причем типизирован он, очевидно, этим самым A — классом, у которого вызвали .class

Если подумать, то понятно зачем это нужно: теперь, в частности, можно написать метод, который возвращает произвольный тип, в зависимости от аргумента:

public T foo(Class clazz); 

A.class возвращает объект класса Class:

Class result = A.class; // Compilation successfull 
2. А что же возвращает a.getClass()?

Собрав воедино все вышесказанное, можно догадаться, что:

Class result1 = a.getClass(); // Compilation error! 

Действительно, ввиду полиморфизма нужно не забывать, что фактический класс объекта a — не обязательно A — это может быть любой подкласс:

Class result = a.getClass(); // Compilation successfull 
3. А что же написано в Object.java?

Все эти дженерики — это, конечно, замечательно, но как записать сигнатуру метода getClass синтаксисом java в классе Object?
А никак:

public final native Class getClass(); 

А на вопрос, почему не компилировался пример выше, ответит Максим Поташев джавадок к методу:

The actual result type is Class where |X| is the erasure of the static type of the expression on which getClass is called.

Так что в Object.java написана одна сигнатура, а компилятор подставляет другую.

Разница между a.getClass() и A.class в Java

В Java класс java.lang.Class является точкой входа для всех операций отражения . Когда у нас есть объект java.lang.Class , мы можем вызывать соответствующие методы для получения объектов классов отражения.

В этом руководстве мы обсудим различия между двумя разными способами получения объекта java.lang.Class :

  • Вызов метода Object.getClass()
  • Использование синтаксиса .class

2. Краткое введение в два подхода​

Метод Object.getClass() является методом экземпляра класса Object . Если у нас есть объект, мы можем вызвать object.getClass() , чтобы получить объект Class его типа.

Точно так же мы можем использовать синтаксис ClassName.class , чтобы получить объект Class типа. Пример может объяснить это ясно:

 @Test   public void givenObjectAndType_whenGettingClassObject_thenTwoMethodsHaveTheSameResult()    String str = "I am an object of the String class";    Class fromStrObject = str.getClass();   Class clazz = String.class;    assertSame(fromStrObject, clazz);   > 

В приведенном выше тестовом методе мы пытаемся получить объект Class класса String , используя два упомянутых нами способа. Наконец, метод утверждения сообщает нам, что два объекта класса являются одним и тем же экземпляром.

Однако между этими двумя подходами есть различия. Давайте рассмотрим их поближе.

3. Тип времени выполнения против статического типа​

Давайте быстро рассмотрим предыдущий пример. Когда мы вызываем метод str.getClass() , мы получаем тип объекта str во время выполнения . С другой стороны, String.class оценивает класс String статически . В этом примере тип времени выполнения str и String.class совпадают.

Однако они могут быть и другими, если к партии присоединится наследование классов. Давайте посмотрим на два простых класса:

 public class Animal    protected int numberOfEyes;   >    public class Monkey extends Animal    // monkey stuff   > 

Теперь давайте создадим объект класса Animal и проведем еще один тест:

 @Test   public void givenClassInheritance_whenGettingRuntimeTypeAndStaticType_thenGetDifferentResult()    Animal animal = new Monkey();    Class runtimeType = animal.getClass();   Class staticType = Animal.class;    assertSame(staticType, runtimeType);   > 

Если мы запустим тест выше, мы получим отказ теста:

 java.lang.AssertionError: ....  Expected :class com.foreach.getclassobject.Animal Actual :class com.foreach.getclassobject.Monkey 

В тестовом методе, даже если мы создали объект животного с помощью Animal animal = new Monkey(); вместо Monkey animal = new Monkey(); , тип объекта животного во время выполнения по- прежнему Monkey. Это связано с тем, что объект животного является экземпляром Monkey во время выполнения.

Однако когда мы получаем статический тип класса Animal , это всегда тип Animal .

4. Работа с примитивными типами​

Когда мы пишем код на Java, мы довольно часто используем примитивные типы. Попробуем получить объект Class примитивного типа, используя подход object.getClass() :

 int number = 7;   Class numberClass = number.getClass(); 

Если мы попытаемся скомпилировать приведенный выше код, мы получим ошибку компиляции:

 Error: java: int cannot be dereferenced 

Компилятор не может разыменовать числовую переменную , поскольку это примитивная переменная. Поэтому метод object.getClass() не может помочь нам получить объект Class примитивного типа.

Давайте посмотрим, сможем ли мы получить примитивный тип, используя синтаксис .class :

 @Test   public void givenPrimitiveType_whenGettingClassObject_thenOnlyStaticTypeWorks()    Class intType = int.class;   assertNotNull(intType);   assertEquals("int", intType.getName());   assertTrue(intType.isPrimitive());   > 

Итак, мы можем получить объект Class примитивного типа int через int.class . В Java версии 9 и более поздних версиях объект Class примитивного типа принадлежит модулю java.base .

Как показывает тест, синтаксис .class — это простой способ получить объект Class примитивного типа.

5. Получение класса без экземпляра​

Мы узнали, что метод object.getClass() может дать нам объект класса его типа во время выполнения .

Теперь давайте рассмотрим случай, когда мы хотим получить объект Class типа, но мы не можем получить экземпляр целевого типа, потому что это абстрактный класс, интерфейс или какой-то класс не допускает создание экземпляров:

 public abstract class SomeAbstractClass    // .   >    interface SomeInterface    // some methods .   >    public class SomeUtils    private SomeUtils()    throw new RuntimeException("This Util class is not allowed to be instantiated!");   >   // some public static methods.   > 

В этих случаях мы не можем получить объекты класса этих типов с помощью метода object.getClass() , но мы все равно можем использовать синтаксис .class для получения их объектов класса :

 @Test   public void givenTypeCannotInstantiate_whenGetTypeStatically_thenGetTypesSuccefully()    Class interfaceType = SomeInterface.class;   Class abstractClassType = SomeAbstractClass.class;   Class utilClassType = SomeUtils.class;    assertNotNull(interfaceType);   assertTrue(interfaceType.isInterface());   assertEquals("SomeInterface", interfaceType.getSimpleName());    assertNotNull(abstractClassType);   assertEquals("SomeAbstractClass", abstractClassType.getSimpleName());    assertNotNull(utilClassType);   assertEquals("SomeUtils", utilClassType.getSimpleName());   > 

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

Поэтому, когда мы хотим иметь объект класса , но не можем получить экземпляр типа, лучше всего использовать синтаксис .class .

6. Заключение​

В этой статье мы узнали о двух разных способах получения объекта Class типа: метод object.getClass() и синтаксис .class .

Позже мы обсудили разницу между этими двумя подходами. Следующая таблица может дать нам четкое представление:

 | | `объект.получитькласс()` | `SomeClass.класс` |  | **Объекты класса** | Тип `объекта во время выполнения` | Статический тип `SomeClass` |  | **Примитивные типы** | — | Работает прямо |  | **Интерфейсы, абстрактные классы или классы, которые не могут быть созданы** | — | Работает прямо | 

Как всегда, полный исходный код статьи доступен на GitHub .

Rukovodstvo

статьи и идеи для разработчиков программного обеспечения и веб-разработчиков.

Методы объектов Java: getClass ()

Введение Эта статья является продолжением серии статей, описывающих часто забываемые методы базового класса Object языка Java. Ниже приведены методы базового объекта Java, присутствующие во всех объектах Java из-за неявного наследования объекта, а также ссылки на каждую статью этой серии. * toString [/ javas-object-methods-tostring /] * getClass (вы здесь) * равно [https://stackabuse.com/javas-object-methods-equals-object] * hashCode [https: // stackabuse. com /

Время чтения: 5 мин.

Вступление

Эта статья является продолжением серии статей, описывающих часто забываемые методы базового класса Object языка Java. Ниже приведены методы базового объекта Java, присутствующие во всех объектах Java из-за неявного наследования объекта, а также ссылки на каждую статью этой серии.

В центре внимания этой статьи - метод getClass() , который используется для доступа к метаданным о классе объекта, с которым вы работаете.

Метод getClass ()

Несколько сбивающий с толку или неправильно понятый метод объекта getClass() возвращает экземпляр класса Class, который содержит информацию о классе, из которого был вызван getClass() Уф, если вы еще не запутались этим последним утверждением, хорошо для вас, потому что я и написал его!

Позвольте мне попытаться раскрыть это предложение, продемонстрировав, как его можно использовать. Ниже вы найдете Person я использовал в первой статье о методе toString()

 package com.adammcquistan.object; import java.time.LocalDate; public class Person < private String firstName; private String lastName; private LocalDate dob; public Person(String firstName, String lastName, LocalDate dob) < this.firstName = firstName; this.lastName = lastName; this.dob = dob; >public String getFirstName() < return firstName; >public void setFirstName(String firstName) < this.firstName = firstName; >public String getLastName() < return lastName; >public void setLastName(String lastName) < this.lastName = lastName; >public LocalDate getDob() < return dob; >public void setDob(LocalDate dob) < this.dob = dob; >@Override public String toString() < return ""; > > 

Давайте сосредоточимся на переопределенном toString() , который перечисляет имя класса Person вместе со значениями полей экземпляра. Вместо «жесткого кодирования» имени класса Person в самой строке я мог бы фактически использовать метод getClass() для возврата экземпляра класса Class, который будет содержать эту информацию и позволит мне использовать ее как так:

 public class Person < // omitting everyting else remaining the same @Override public String toString() < Class c = getClass(); return ""; > > 

Это приведет к замене исходного жестко запрограммированного текста «Person» на полное имя класса «com.adammcquistan.object.Person». Класс Class наполнен различными методами, которые позволяют идентифицировать все аспекты объекта класса, для которого был вызван getClass()

Например, если я хотел бы получить более упрощена toString() представление моего Person класса я мог бы просто поменять на c.getName() вызов с c.getSimpleName() , как показано ниже. Это, в свою очередь, вернет «Человек» вместо полного имени класса «com.adammcquistan.object.Person».

 public class Person < // omitting everyting else remaining the same @Override public String toString() < Class c = getClass(); return ""; > > 

Основное различие в семантике использования getClass() по сравнению с другими Object заключается в том, что getClass() нельзя переопределить, поскольку он объявлен как final метод.

Для чего подходит объект класса?

В этот момент вы можете спросить себя: «Хорошо, я думаю, это довольно круто, что я могу получить информацию о классе, вызвав getClass () и получив его представление объекта Class, но как это полезно для меня как программиста?». Поверьте, я тоже задавал себе этот вопрос, и мой общий вывод был . это не так. По крайней мере, это не совсем так с точки зрения обычного программиста . Однако, если вы являетесь разработчиком библиотеки или фреймворка, вы, вероятно, хорошо познакомитесь с информацией и поведением Class потому что это важно для концепции, известной как отражение .

Отражение позволяет выполнять две основные задачи: (i) исследование объектов и их содержимого во время выполнения и (ii) динамический доступ к полям и выполнение методов во время выполнения.

Элемент номер один уже был продемонстрирован выше с использованием getClass() для получения представления Person во время выполнения для доступа либо к полному, либо к простому имени класса в модифицированной версии метода toString() .

Второй элемент немного сложнее для создания примера, но это то, что очень полезно для доступа к метаданным в классе. Некоторая информация, которую вы можете запросить у экземпляра Class - это такие вещи, как конструкторы, поля и методы, а также другие вещи, такие как иерархии наследования класса, такие как суперклассы и интерфейсы.

Примером этого является возможность использовать отладчики в среде IDE, например Eclipse и Netbeans, для просмотра членов и их значений в классе во время выполнения программы.

Возьмем, к примеру, следующее:

 public class Main < public static void main(String[] args) < Person me = new Person("Adam", "McQuistan", LocalDate.parse("1987-09-23")); Class c = me.getClass(); for (Field f : c.getDeclaredFields()) < f.setAccessible(true); try < System.out.println(f.getName() + " = " + f.get(me)); >catch (Exception e) < e.printStackTrace(); >> > > 
 firstName = Adam lastName = McQuistan dob = 1987-09-23 

Опять же, ни один немазохист, вероятно, никогда бы не сделал этого в обычном повседневном программировании, но вы увидите, что такие вещи часто выполняются во фреймворках.

Заключение

В этой статье я описал значение и использование загадочного getClass() класса Java Object. Я показал, как его можно использовать для получения метаданных об экземпляре класса, таких как имя класса объекта во время выполнения, а также объяснил, почему доступ к экземпляру класса может быть полезен.

Как всегда, спасибо за чтение и не стесняйтесь комментировать или критиковать ниже.

Licensed under CC BY-NC-SA 4.0

Java Blog

Класс Object является корнем иерархии классов. У каждого класса есть Object как суперкласс. Все объекты, включая массивы, реализуют методы этого класса.

Методы класса Object

Метод getClass()
public final Class getClass()

Возвращает класс времени исполнения (runtime class) этого Object. Возвращенный объект Class - это объект, который заблокирован статическими синхронизированными методами представленного класса.

Фактический тип результата - Class где |X| заменяется статическим типом выражения, для которого вызывается getClass. Например, в этом фрагменте кода не требуется приведение:

Number n = 0; Class c = n.getClass();

Метод getClass() возвращает:

Объект Class, представляющий класс времени исполнения (runtime class) этого объекта.

Метод hashCode
public int hashCode()

Возвращает значение хэш-кода для объекта. Этот метод поддерживается для использования хэш-таблиц, таких как те, что предоставляются HashMap.

Основной контракт метода hashCode:

  • Всякий раз, когда он вызывается для одного и того же объекта более одного раза во время выполнения приложения Java, метод hashCode должен последовательно возвращать одно и то же целое число при условии, что никакая информация, используемая в сравнениях equals для объекта, не изменяется. Это целое число не должно оставаться согласованным между одним исполнением приложения и другим исполнением того же приложения.
  • Если два объекта равны в соответствии с методом equals(Object), то вызов метода hashCode для каждого из двух объектов должен привести к одному и тому же целочисленному результату.
  • Не требуется, чтобы, если два объекта были неравны в соответствии с методом equals(java.lang.Object), то вызов метода hashCode для каждого из двух объектов должен давать разные целочисленные результаты. Тем не менее, программист должен знать, что выдача различных целочисленных результатов для неравных объектов может повысить производительность хэш-таблиц.

Насколько это практически целесообразно, метод hashCode, определенный классом Object, возвращает разные целые числа для разных объектов. (Обычно это реализуется путем преобразования внутреннего адреса объекта в целое число, но этот метод реализации не требуется языком программирования Java.)

Метод hashCode возвращает:

Целочисленное (int) значение хэш-кода для этого объекта.

Метод equals
public boolean equals(Object obj)

Указывает, равен ли какой-либо другой объект этому объекту.

Метод equals реализует отношение эквивалентности для ненулевых ссылок на объекты:

  • Оно рефлексивно: для любого ненулевого ссылочного значения x, x.equals(x) должно возвращать true.
  • Оно симметрично: для любых ненулевых ссылочных значений x и y x.equals(y) должен возвращать true, только если y.equals(x) возвращает true.
  • Оно транзитивно: для любых ненулевых ссылочных значений x, y и z, если x.equals(y) возвращает true, а y.equals(z) возвращает true, тогда x.equals(z) должен возвращать true.
  • Оно непротиворечиво (консистентно): для любых ненулевых ссылочных значений x и y множественные вызовы x.equals(y) последовательно возвращают true или последовательно возвращают false при условии, что никакая информация, используемая в сравнениях equals на объектах, не изменяется.
  • Для любого ненулевого ссылочного значения x, x.equals(null) должен возвращать false.

Метод equals для класса Object реализует максимально различающее возможное отношение эквивалентности на объектах; то есть для любых ненулевых ссылочных значений x и y этот метод возвращает true только тогда, когда x и y ссылаются на один и тот же объект (x == y имеет значение true).

Обратите внимание, что обычно необходимо переопределять метод hashCode всякий раз, когда метод equals переопределяется, чтобы поддерживать общий контракт для метода hashCode, в котором говорится, что равные объекты должны иметь одинаковые хэш-коды.

obj - эталонный объект для сравнения.

Метод equals возвращает:

Значение true, если этот объект совпадает с аргументом obj; false в противном случае.

Метод clone
protected Object clone() throws CloneNotSupportedException

Создает и возвращает копию этого объекта. Точное значение "копия" может зависеть от класса объекта. Общее намерение состоит в том, что для любого объекта x, выражение:

x.clone() != x

будет верно, и это выражение:

x.clone().getClass() == x.getClass()

будет верно, но это не абсолютные требования. Хотя обычно это так:

x.clone().equals(x)

будет верно, это не является абсолютным требованием.

По соглашению, возвращаемый объект должен быть получен путем вызова super.clone. Если класс и все его суперклассы (кроме Object) подчиняются этому соглашению, это будет иметь место в том случае, если x.clone().getClass() == x.getClass().

По соглашению объект, возвращаемый этим методом, должен быть независимым от этого объекта (который клонируется). Для достижения этой независимости может потребоваться изменить одно или несколько полей объекта, возвращаемого super.clone, перед его возвратом. Как правило, это означает копирование любых изменяемых объектов, которые составляют внутреннюю "глубокую структуру" клонируемого объекта, и замену ссылок на эти объекты ссылками на копии. Если класс содержит только примитивные поля или ссылки на неизменяемые объекты, то обычно бывает так, что нет необходимости изменять поля в объекте, возвращаемом super.clone.

Метод clone для класса Object выполняет определенную операцию клонирования. Во-первых, если класс этого объекта не реализует интерфейс Cloneable, генерируется исключение CloneNotSupportedException. Обратите внимание, что считается, что все массивы реализуют интерфейс Cloneable и что тип возвращаемого значения метода clone типа массива T[] равен T[], где T - любой ссылочный или примитивный тип. В противном случае этот метод создает новый экземпляр класса этого объекта и инициализирует все его поля точно содержимым соответствующих полей этого объекта, как если бы он был назначен; содержимое полей не клонируется. Таким образом, этот метод выполняет "поверхностную копию" ("shallow copy") этого объекта, а не "глубокую копию" ("deep copy").

Класс Object сам по себе не реализует интерфейс Cloneable, поэтому вызов метода clone для объекта, класс которого Object, приведет к возникновению исключения во время выполнения.

Метод clone возвращает:

клон этого экземпляра.

Метод clone выбрасывает:

CloneNotSupportedException - если класс объекта не поддерживает интерфейс Cloneable. Подклассы, которые переопределяют метод clone, могут также выдать это исключение, чтобы указать, что экземпляр не может быть клонирован.

Метод toString
public String toString()

Возвращает строковое представление объекта. В общем случае метод toString возвращает строку, которая является "текстовым представлением" этого объекта. Результатом должно быть краткое, но информативное представление, которое легко читается человеком. Рекомендуется, чтобы все подклассы переопределяли этот метод.

Метод toString для класса Object возвращает строку, состоящую из имени класса, экземпляром которого является объект, символа знака "@" и шестнадцатеричного представления без знака хэш-кода объекта. Другими словами, этот метод возвращает строку, равную значению:

getClass().getName() + '@' + Integer.toHexString(hashCode())

Метод toString возвращает:

строковое представление объекта.

Метод notify
public final void notify()

Пробуждает один поток, который ожидает на мониторе этого объекта. Если какие-либо потоки ожидают этого объекта, один из них выбирается для пробуждения. Выбор является произвольным и происходит на усмотрение реализации. Поток ожидает на мониторе объекта, вызывая один из методов wait.

Пробужденный поток не сможет продолжить работу, пока текущий поток не снимет блокировку этого объекта. Пробужденный поток будет конкурировать обычным образом с любыми другими потоками, которые могут активно конкурировать за синхронизацию на этом объекте; например, пробужденный поток не имеет надежных привилегий или недостатков в качестве следующего потока для блокировки этого объекта.

Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта. Поток становится владельцем монитора объекта одним из трех способов:

  • Выполняя synchronized метод экземпляра этого объекта.
  • Выполняя тело synchronized выражения, которое синхронизируется на объекте.
  • Для объектов типа Class, выполняя synchronized static метод этого класса.

Только один поток одновременно может владеть монитором объекта.

IllegalMonitorStateException - если текущий поток не является владельцем монитора этого объекта.

Метод notifyAll
public final void notifyAll()

Пробуждает все потоки, которые ожидают на мониторе этого объекта. Поток ожидает на мониторе объекта, вызывая один из методов wait.

Пробужденные потоки не смогут продолжить работу, пока текущий поток не снимет блокировку этого объекта. Пробужденные потоки будут конкурировать обычным образом с любыми другими потоками, которые могут активно конкурировать за синхронизацию на этом объекте; например, пробужденные потоки не имеют надежных привилегий или недостатков в качестве следующего потока для блокировки этого объекта.

Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта.

IllegalMonitorStateException - если текущий поток не является владельцем монитора этого объекта.

Метод wait с аргументом timeout
public final void wait(long timeout) throws InterruptedException

Заставляет текущий поток ждать, пока другой поток не вызовет метод notify() или метод notifyAll() для этого объекта, или пока не истечет указанное количество времени.

Текущий поток должен владеть монитором этого объекта.

Этот метод заставляет текущий поток (назовем его T) поместить себя в набор ожидания для этого объекта, а затем отказаться от любых заявлений на синхронизацию этого объекта. Поток T становится отключенным для целей планирования потоков и остается бездействующим, пока не произойдет одно из четырех:

  • Какой-то другой поток вызывает метод notify для этого объекта, и поток T случайно выбирается в качестве потока, который нужно пробудить.
  • Другой поток вызывает метод notifyAll для этого объекта.
  • Какой-то другой поток прерывает поток Т.
  • Указанное количество реального времени истекло, более или менее. Однако, если timeout равен нулю, то реальное время не учитывается, и поток просто ждет, пока не получит уведомление.

Затем поток T удаляется из набора ожидания для этого объекта и снова включается для планирования потока. Затем он конкурирует обычным образом с другими потоками за право синхронизации на объекте; как только он получил контроль над объектом, все его заявки на синхронизацию с объектом восстанавливаются до состояния quo ante, то есть ситуации на момент вызова метода wait. Затем поток T возвращается из вызова метода ожидания. Таким образом, при возврате из метода ожидания состояние синхронизации объекта и потока Т точно такое же, как и при вызове метода ожидания.

Поток также может просыпаться без уведомления, прерывания или истечения тайм-аута, так называемое ложное пробуждение (spurious wakeup). Хотя это редко случается на практике, приложения должны защищаться от него, проверяя условие, которое должно было вызвать пробуждение потока, и продолжая ждать, если условие не выполняется. Другими словами, ожидания всегда должны происходить в циклах, например:

synchronized (obj) < while () obj.wait(timeout); . // Выполняем действие подходящее для условия >

Если текущий поток прерывается каким-либо потоком до или во время ожидания, генерируется исключение InterruptedException. Это исключение не выдается, пока состояние блокировки этого объекта не будет восстановлено, как описано выше.

Обратите внимание, что метод wait, поскольку он помещает текущий поток в набор ожидания для этого объекта, разблокирует только этот объект; любые другие объекты, по которым текущий поток может быть синхронизирован, остаются заблокированными, пока поток ожидает.

Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта.

Параметры: timeout - максимальное время ожидания в миллисекундах.

IllegalArgumentException - если значение timeout является отрицательным.

IllegalMonitorStateException - если текущий поток не является владельцем монитора объекта.

InterruptedException - если какой-либо поток прерывал текущий поток до или в то время, когда текущий поток ожидал уведомления. Прерванное состояние текущего потока очищается при возникновении этого исключения.

Метод wait с аргументами timeout и nanos
public final void wait(long timeout, int nanos) throws InterruptedException

Заставляет текущий поток ждать, пока другой поток не вызовет метод notify() или метод notifyAll() для этого объекта, или какой-либо другой поток прервет текущий поток, или пока не истекло определенное количество реального времени.

Этот метод аналогичен методу wait с одним аргументом, но он позволяет лучше контролировать время ожидания уведомления перед тем, как отказаться. Количество реального времени, измеряемое в наносекундах, определяется как:

1000000*timeout+nanos

Во всех других отношениях этот метод делает то же самое, что и метод wait(long) с одним аргументом. В частности, wait(0, 0) означает то же самое, что и wait(0).

Текущий поток должен владеть монитором этого объекта. Поток освобождает владельца этого монитора и ожидает, пока не произойдет одно из следующих двух условий:

  • Другой поток уведомляет потоки, ожидающие на мониторе этого объекта, чтобы он проснулся либо посредством вызова метода notify, либо метода notifyAll.
  • Истек срок ожидания, указанный аргументами: timeout миллисекунд плюс nanos наносекунд.

Затем поток ожидает, пока не получит право собственности на монитор, и возобновит выполнение.

Как и в версии с одним аргументом, возможны прерывания и ложные пробуждения, и этот метод всегда должен использоваться в цикле:

synchronized (obj) < while () obj.wait(timeout, nanos); . // Выполняем действие подходящее для условия >

Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта.

Параметры:
timeout - максимальное время ожидания в миллисекундах.
nanos - дополнительное время в диапазоне наносекунд 0-999999.

IllegalArgumentException - если значение timeout является отрицательным или значение nanos не находится в диапазоне 0-999999.

IllegalMonitorStateException - если текущий поток не является владельцем монитора этого объекта.

InterruptedException - если какой-либо поток прерывал текущий поток до или в то время, когда текущий поток ожидал уведомления. Прерванное состояние текущего потока очищается при возникновении этого исключения.

Метод wait без аргументов
public final void wait() throws InterruptedException

Заставляет текущий поток ждать, пока другой поток не вызовет метод notify() или метод notifyAll() для этого объекта. Другими словами, этот метод ведет себя точно так же, как если бы он просто выполнял вызов wait(0).

Текущий поток должен владеть монитором этого объекта. Поток освобождает владельца этого монитора и ожидает, пока другой поток не уведомит потоки, ожидающие на мониторе этого объекта, чтобы он проснулся либо посредством вызова метода notify, либо метода notifyAll. Затем поток ожидает, пока не получит право собственности на монитор, и возобновит выполнение.

Как и в версии с одним аргументом, возможны прерывания и ложные пробуждения, и этот метод всегда должен использоваться в цикле:

synchronized (obj) < while () obj.wait(); . // Выполняем действие подходящее для условия >

Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта.

IllegalMonitorStateException - если текущий поток не является владельцем монитора этого объекта.

InterruptedException - если какой-либо поток прерывал текущий поток до или в то время, когда текущий поток ожидал уведомления. Прерванное состояние текущего потока очищается при возникновении этого исключения.

Метод finalize
protected void finalize() throws Throwable

Вызывается сборщиком мусора на объекте, когда сборщик мусора определяет, что больше нет ссылок на объект. Подкласс переопределяет метод finalize для удаления системных ресурсов или для другой очистки.

Общий контракт finalize заключается в том, что он вызывается, если и когда виртуальная машина Java определила, что больше нет никаких средств, с помощью которых этот объект мог бы быть доступен любому потоку, который еще жив, кроме как в результате действия берется финализацией какого-то другого объекта или класса, который готов к финализации. Метод finalize может выполнять любые действия, включая повторное предоставление этого объекта другим потокам; однако обычная цель finalize - выполнить действия по очистке до того, как объект будет безвозвратно удален. Например, метод finalize для объекта, который представляет соединение ввода-вывода, может выполнять явные транзакции ввода-вывода, чтобы разорвать соединение до того, как объект будет окончательно удален.

Метод finalize класса Object не выполняет никаких специальных действий; он просто выполняет возврат. Подклассы Object могут переопределить это поведение.

Язык программирования Java не гарантирует, какой поток вызовет метод finalize для любого данного объекта. Однако гарантируется, что поток, который вызывает finalize, не будет удерживать видимые пользователем блокировки синхронизации, когда вызывается finalize. Если с помощью метода finalize генерируется неперехваченное исключение, оно игнорируется, и финализация этого объекта завершается.

После того, как метод finalize был вызван для объекта, никакие дальнейшие действия не предпринимаются, пока виртуальная машина Java снова не определит, что больше нет никаких средств, с помощью которых этот объект мог бы быть доступен любому потоку, который еще не жив, включая возможные действия другими объектами или классами, которые готовы к финализации, после чего объект может быть удален.

Метод finalize никогда не вызывается виртуальной машиной Java более одного раза для любого данного объекта.

Любое исключение, выброшенное методом finalize, приводит к остановке завершения этого объекта, но в противном случае игнорируется.

Throwable - Exception, возбуждаемое этим методом

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *