Содержание и принципы работы основной библиотеки Java – java.lang. Оценка значения классов Object и Class, оберток для примитивных типов, Math, String и StringBuffer, System, Runtime. Классы для работы с исключительными ситуациями и потоками исполнения.
В состав пакета java.lang входят классы, составляющие основу для всех других - изза чего он является наиболее важным из всех, входящих в Java API. Каждый класс в Java неявным образом (по умолчанию) импортирует все классы этого пакета - можно не писать import java.lang.*;.
Основу пакета составляют классы: Object- является корневым в иерархии классов. Если при описании класса не указывается родительский, то им считается класс Object. Все объекты, включая массивы, наследуются от этого класса.
Class - экземпляры этого класса представляют классы и интерфейсы в запущенной Java-программе.
String - представляет средства работы с символьными строками
STRINGBUFFER - используется для работы (создания) строк
Number - абстрактный класс, являющийся суперклассом для классов-объектных оберток числовых примитивных типов Java
Character - объектная обертка для типа char
Boolean- объектная обертка для типа boolean
Math - реализует ряд наиболее известных математических функций
Throwable- базовый класс для объектов, представляющих исключения. Любое исключение, которое может быть брошено и, соответственно, перехвачено блоком catch, должно быть унаследовано от Throwable
Thread- представляет вычислительный поток в Java. Виртуальная машина Java позволяет одновременно выполнять несколько потоков
THREADGROUP - позволяет объединять потоки в группу, и производить действия сразу над всеми потоками в ней. Сущствуют ограничения по безопасности на манипуляции с потоками из других групп. операции над потоком могут проводиться только потоком, относящимся к той же группе.
System - содержит полезные поля и методы для работы системного уровня
Runtime- позволяет приложению взаимодействовать с окружением в котором оно запущено
Process - представляет внешнюю программу, запущенную при помощи Runtime
CLASSLOADER - отвечает за загрузку классов
SECURITYMANAGER - для обеспечения безопасности накладывает ограничения на данную среду выполнения программ
Compiler - используется для поддержки Just-in-Time компиляторов
Интерфейсы: Cloneable - должен быть реализован объектами, которые планируется клонировать с помощью средств JVM (Object.clone())
Программирование на Java
Rendered by www.RENDERX.com
Стр. 3 из 33
Runnable - может использоваться в сочетании с классом Thread, позволяя реализовать метод run(), котрый будет вызван при старте данного потока.
Comparable- позволяет упорядочивать (сортировать, сравнивать) объекты каждого класса, реализующего этот интерфейс.
2. Object
Класс Object является базовым для всех остальных классов. Он определяет методы, которые поддерживаются любым классом в Java.
Это методы: 1.0) public boolean equals(Object obj) - определяет, являются ли объекты одинаковыми. Если оператор == определяет равенство именно объектных ссылок, то метод equals() определяет, содержат ли объекты одинаковую информацию. Реализация этого метода в классе Object такова, что значение true будет возвращено тогда и только тогда, если объектные ссылки переданного объекта и объекта, у которого вызывается метод совпадают, то есть:
public boolean equals(Object obj) { return (this == obj);
}
В классах - наследниках, этот метод при необходимости может быть переопределен, что бы отражать действительное равенство объектов. Например, сравнение объектов-оберток целых чисел (класс Integer), должно по всей логике возвращать значение true, если равны значения int чисел, которые обернуты, даже если различаются объектные ссылки на сами объекты класса-обертки Integer.
Метод equals() может быть переопределен любым способом (например, всегда возвращает false, или, наоборот, - true) - компилятор, конечно же, не будет проводить анализ реализации и давать рекомендации, НО: реализация метода предполагается с учетом следующих правил: 1. рефлексивность: для любой объектной ссылки x, вызов x.equals(x) возвращает true
2. симметричность: для любых объектных ссылок хи y, вызов x.equals(y) возвращает true тогда и только тогда, если вызов y.equals(x) возвращает true
3. транзитивность: для любых объектных ссылок x, y и z, если x.equals(y)возвращает true и y.equals(z) возвращает true, тогда вызов x.equals(z) должен вернуть true
4. непротиворечивость: для любых объектных ссылок x и y, многократные последовательные вызовы x.equals(y)возвращают одно и то же значение (либо всегда true либо всегда false)
5. для любой не равной null объектной ссылки x, вызов x.equals(null) должен вернуть значение false
Пример:
package demo.lang;
Программирование на Java
Rendered by www.RENDERX.com
Стр. 4 из 33 Object
public class Rectangle { public int SIDEA; trialc int SIDEB;
В этом примере метод equals() у класса Retangle был переопределен таким образом, что бы прямоугольники были равны, если их можно наложить друг на друга (геометрическое равенство).
1.1) public int HASHCODE() - возвращает хеш-код (hash code) для объекта. Хеш-код - это целое число, которое с очень большой вероятностью является уникальным для данного объекта. Это значение используется классом Hashtable для хранения с возможностью быстрой выборки объектов(хеш-код используется для группировки объектов, и при поиске объекта достаточно просмотреть только блок, соответствующий его хеш-коду)
Обычно вполне можно пользоваться стандартной реализацией, но если же будет принято решение измtrial метод вычисления хеш-кода, то необходимо убедиться, что в этом случае будет вtrialщаться одно и то же значение для равных между собой объектов. То есть, если x.equals(y)возвращает true, то хеш-коды x и y должны совпадать, то есть вызовы
Программирование на Java
Rendered by www.RENDERX.com
Стр. 5 из 33 x.HASHCODE() и y.HASHCODE() должны возвращать одно и то же значение. В противном случае Hashtable будет считать объекты различными, не вызывая метод equals()
Формально правила, которым должна следовать реализация метода, формулируется следующим образом: a) в одном запуске программы, для одного объекта, при вызове метода HASHCODE(), должно возвращаться одно и то же int значение, если между этими вызовами НЕ были затронуты данные, используемые для проверки объектов на идентичность в методе equals(). Это число НЕ обязано быть одним и тем же при повторном запуске той же программы, даже если все данные будут идентичны b) если два объекта идентичны, то есть вызов метода equals(Object) возвращает true, тогда вызов метода HASHCODE() у каждого из этих двух объектов должен возвращать одно и то же значение c) если два объекта различны, то есть вызов метода equals(Object) возвращает false, тогда различие их хеш-кодов желательно, но НЕ обязательно. Различие в хеш-кодах для НЕ идентичных объектов нужно только для обеспечения хорошей производительности при использовании этих объектов в хеш-таблицах.
В классе Object реализация метода HASHCODE() использует для получения результата преобразование внутреннего адреса объекта в памяти, поэтому если не перекрывать эту реализацию, то для разных объектов будут возвращены различные значения.
1.2) public String TOSTRING() - возвращает строковое представление объекта. В классе Object этот метод реализован следующим образом:
public String TOSTRING() { return GETCLASS().GETNAME() "@" Integer.TOHEXSTRING(HASHCODE()); }
То есть возвращает строку, содержащую название класса объекта и его хеш-код.
В классах-наследниках этот метод может быть переопределен для получения более наглядного пользовательского представления объекта. Обычно это значения некоторых полей, характеризующих экземпляр. Например, для книги это может быть название, автор и количество страниц:
package demo.lang;
public class Book { private String title; private String author; private int PAGESNUMBER;
public Book(String title, String author, int PAGESNUMBER) { super();
this.title = title; this.author = author;
this.PAGESNUMBER = PAGESNUMBER; } public static void main(String[] args) {
Программирование на Java
Rendered by www.RENDERX.com
Стр. 6 из 33 Object
Book book = new Book("Java2", "Sun", 1000); System.out.println("object is: " book);
} public String TOSTRING(){ return "Book: " title " ( " author ", " PAGESNUMBER " pages )"; }
}
При запуске этой программы, на экран будет выведено следующее:
object is: Book: Java2 ( Sun, 1000 pages )
То есть, для получения строкового представления объекта book, был вызван его метод TOSTRING() (оператор " " определен для строк таким образом, что все операнды будут сначала приведены к String, для объектов в этом случае вызывается метод TOSTRING()).
1.3) wait(), notify(), NOTIFYALL() - эти методы используются для поддержки многопоточности. Они определены с атрибутом final и НЕ могут быть переопределены в классах-наследниках.
1.4) protected void finalize() throws Throwable - этот метод вызывается Java-машиной перед тем, как garbage collection (сборщик мусора) очистит память, занимаемую объектом. Работа сборщика мусора и описание схемы, по которой производится вызов метода finaliuze() приведено в соответствующей главе. Здесь же ограничимся только напоминанием, что объект считается пригодным для сборщика мусора, когда выполняющейся части программы не будет доступно ни одной ссылки на объект. Перед очисткой занимаемой объектом памяти, будет произведен вызов его метода finalize().
Реализация этого метода в классе Object - не производит никаких действий. В классах-наследниках этот метод может быть переопределен для проведения всех необходимых действий по освобождению различных занимаемых ресурсов - закрытия сетевых соединений, файлов и т.д.
1.5) protected native Object clone() throws CLONENOTSUPPORTEDEXCEPTION - создает копию объекта. Для того, что бы им можно было воспользоваться, объект должен реализовывать интерфейс Cloneable. Этот интерфейс не определяет никаких методов, определение, что класс его реализует - только символизирует, что можно создавать копии объектов этого класса. В классе Object метод clone() реализован таким образом, что будут скопированы только базовые типы и ссылки на объекты. Если же потребуется "глубокое " копирование, то есть скопировать не только ссылки на объекты, но и создать копии объектов - в классах-наследниках метод clone() можно переопределить.
Например, в следующем примере:
package demo.lang;
public class BOOKSTORAGE implements Cloneable{ public Book[] books;
public BOOKSTORAGE() { books = new Book[2];
books[0] = new Book("Essential java", "Sun", 500); books[1] = new Book("Professional Java", "Sun", 1000);
То изменения затронут и объект storage1 - изменится содержимое массива books. Это произойдет, потому что реализация метода clone() по умолчанию скопирует только ссылку на массив, поэтому изменение его содержимого затронет оба объекта: storage1 и storage2. Если же мы хотим, что бы копировались не только ссылки, имеющиеся в объекте, но объекты, на которые имеются ссылки, необходимо соответствующим образом переопределить метод clone(). В случае данного примера, это можно сделать следующим образом:
Теперь будет создаваться копия не только BOOKSTORAGE, но и массива books. Это легко проверить, еще раз запустив вышеприведенный код.
1.6) public final native Class GETCLASS() - возвращает объект типа Class, соответствующий классу объекта. Именно этот объект используется при использовании синхронизации статических методов.
3. Class
В запущенной программе Java каждому классу соответствует объект типа Class. Этот объект содержит информацию, необходимую для описания класса - поля, методы и т.д.
Класс Class не имеет открытого конструктора - объекты этого класса создаются автоматически Java-машиной по мере загрузки классов и вызовов метода DEFINECLASS() загрузчика классов. Получить экземпляр Class для конкретного класса можно воспользовавшись методом FORNAME(): 2.1) public static Class FORNAME(String name, boolean initialize, CLASSLOADER loader) - возвращает объект Class, соответствующий классу или интерфейсу с названием, указанным в name (необходимо указывать полное название класса или интерфейса), используя переданный загрузчик классов. Если в качестве загрузчика классов loader передано значение null, будет взят таковой, который использовался для загрузки вызывающего класса. При этом класс будет инициализирован, только если значение initialize равно true и класс не был инициализирован ранее.
Программирование на Java
Rendered by www.RENDERX.com
Стр. 8 из 33 Class
Довольно часто проще и удобнее воспользоваться методом FORNAME(), передав только название класса: public static Class FORNAME(String CLASSNAME) - при этом будет использоваться загрузчик вызывающего класса, и класс будет инициализирован, если до этого не был.
2.2) public Object NEWINSTANCE() - создает и возвращает объект класса, который представляется данным экземпляром Class. Создание будет проходить, используя конструктор без параметров. Если такового в классе нет, будет брошено исключение INSTANTIATIONEXCEPTION. Это же исключение будет брошено, если объект Class соответствует абстрактному классу, интерфейсу или же по какой-либо другой причине.
2.3) Каждому методу, полю, конструктору класса так же соответствуют объекты, которые можно получить вызовом соответствующих методов на объекте Class: GETMETHODS(), GETFIELDS(), GETCONSTRUCTORS(),GETDECLAREDMETHODS() и т.д. В результате будут получены объекты, которые отвечают за поля, методы, конструкторы объекта. Их можно использовать для формирования динамических вызовов Java - такой процесс называется отражение (reflection). Классы, используемые для отражения содержатся в пакете java.lang.reflection.
Динамическое создание экземпляров не обязательно всегда сопровождается вызовом методов посредством отражения. Это показано в следующем примере:
package demo.lang; interface Vehicle { void go();
} class Automobile implements Vehicle { public void go() {
System.out.println("Automobile go!"); }
} class Truck implements Vehicle { public Truck(int i) { super(); } public void go() { System.out.println("Truck go!");
} } public class VEHICLESTARTER { public static void main(String[] args) { Vehicle vehicle;
Если запустить эту программу, на экран будет выведено следующее:
look for clas for: demo.lang.Automobile creating vehicle... create vehicle: class demo.lang.Automobile Automobile go! look for clas for: demo.lang.Truck creating vehicle...
Instantiation exception: java.lang.INSTANTIATIONEXCEPTION look for clas for: demo.lang.Tank
Class not found: java.lang.CLASSNOTFOUNDEXCEPTION: demo.lang.Tank
Как видим, объект класса Automobile был успешно создан, а дальше с ним работа велась через интерфейс Vehicle. А вот класс Truck был найден, но при создании объекта этого класса, было брошено и, соответственно, обработано исключение java.lang.INSTANTIATIONEXCEPTION. Так-как класс java.lang.Tank не был определен, то при попытке получить объект Class, ему соответствующий, было брошено исключение java.lang.CLASSNOTFOUNDEXCEPTION.
4. Wrapper Classes
Во многих случаях бывает предпочтительней работать именно с объектами, а не примитивными типами. Так, например, при использовании коллекций, просто необходимо значения примитивных типов каким-то образом представлять в виде объектов. Для этих целей и предназначены так называемые классы-обертки. Для каждого примитивного типа Java существует свой класс обертка. Такой класс является неизменяемым (то есть, для изменения значения необходимо создавать новый объект), к тому же имеет атрибут final - от него нельзя наследовать класс. Все классы-обертки (кроме Void) реализуют интерфейс Serializable, поэтому объекты любого (кроме Void) класса-обертки могут быть сериализованы. Все классы-обертки содержат статическое поле TYPE - содержащее объект Class, соответствующий примитивному оборачиваемому типу.
Так же классы-обертки содержат статические методы для обеспечения удобного манипулирования соответствующими примитивными типами, например преобразование к строковому виду.
Программирование на Java
Rendered by www.RENDERX.com
Стр. 10 из 33 Wrapper Classes
В таблице 1 описаны примитивные типы и соответствующие им классы обертки:
Класс-обертка
Byte
Short
Character
Integer
Long
Float
Double
Boolean
Примитивный тип byte short char int long float double boolean
При этом классы обертки числовых типов - Byte, Short, Integer, Long, Float, Double наследуются от одного класса - Number. В нем содержится код, общий (часть реализована посредством абстрактных методов) для всех классов-оберток числовых типов -примитивного значения в виде byte, short, int, long, float и double.
Все классы-обертки реализуют интерфейс Comparable. Number реализует интерфейс java.io.Serializable, поэтому все объекты классов-оберток примитивных числовых типов могут быть сериализованы.
Все классы-обертки числовых типов имеют метод equals(Object), сравнивающий примитивные значения объектов.
Стоит быть особо внимательным - результат выполнения (new Integer(1)).equals(new Byte(1)) дает false, хотя сами значения, вокруг которых обернуты объекты - равны. Такой результат получается потому, что во всех таких классах, метод equals() определен таким образом, что сначала производится проверка, совпадают ли типы (классы) значений, и если нет - сразу возвращается false. Например в jdk1.3.1 для Integer метод equals() определен следующим образом:
public boolean equals(java.lang.Object obj) { if(obj instanceof java.lang.Integer) return value == ((java.lang.Integer)obj).INTVALUE(); else return false; }
Рассмотрим более подробно некоторые из классов-оберток.
4.1. Integer
Наиболее часто используемые статические методы. public static int PARSEINT(String s) - преобразует в int значение строку, представляющую десятичную запись целого числа public static int PARSEINT(String s, int radix) - преобразует в int значение строку, представляющую запись целого числа в системе счисления radix
Оба этих метода могут возбуждать исключение NUMBERFORMATEXCEPTION, если строка, переданная на вход, содержит нецифровые символы.
Не следует путать эти методы, с другой парой похожих методов: public static Integer VALUEOF(String s) public static Integer VALUEOF(String s,int radix)
Программирование на Java
Rendered by www.RENDERX.com
Integer Стр. 11 из 33
Эти методы выполняют аналогичную работу, только результат представляют в виде объекта-обертки.
Существует так же два конструктора для создания экземпляров в класса Integer
Integer(String s) - такой метод, принимающий в качестве параметра строку, представляющую значение, имеется для каждого класса
Integer(int i) - аналогично, для каждого класса-обертки числового примитивного типа, имеется конструктор, принимающий значение оборачиваемого примитивного типа
Первый вариант конструктора так же может возбуждать исключение NUMBERFORMATEXCEPTION pubic static String TOSTRING(int i) - используется для преобразования значения типа int в строку
Далее перечислены методы, преобразующие int в строковое восьмеричное, двоичное и шестнадцатеричное представление: pubic static String TOOCTALSTRING(int i) - восьмеричное pubic static String TOBINARYSTRING(int i) - двоичное pubic static String TOHEXSTRING(int i) - шестнадцатиричное .
Имеется так же две статические константы: Integer.MIN_VALUE - минимальное int значение
Integer.MAX_VALUE - максимальное int значение.
Аналогичны константы, равные границам соответствующих типов, определены и для всех остальных классов-оберток числовых примитивных типов. public int INTVALUE();
возвращает значение примитивного типа для данного Integer. Классы-обертки остальных примитивных целочисленных типов: Byte, Short, Long содержат только аналогичные методы и константы, только определенные для соответствующих типов: byte, short, long. trialp:
public static void main(String[] args) { int i = 1;
byte b = 1;
String value = "1000";
Integer IOBJ = new Integer(i); Byte BOBJ = new Byte(b);
System.out.println("while i==b is " (i==b)); System.out.println("IOBJ.equals(BOBJ) is " IOBJ.equals(BOBJ)); Long LOBJ = new Long(value);
System.out.println("LOBJ = " LOBJ.TOSTRING());
Long sum = new Long(LOBJ.LONGVALUE() IOBJ.BYTEVALUE() BOBJ.SHORTVALUE());
System.out.println("The sum = " sum.DOUBLEVALUE()); }
Программирование на Java
Rendered by www.RENDERX.com
Стр. 12 из 33 Wrapper Classes
В данном примере произвольным образом используются различные варианты классов-оберток и их методов. Соответственно, в результате выполнения, на экран будет выведено следующее:
while i==b is true IOBJ.equals(BOBJ) is false LOBJ = 1000
The sum = 1002.0
Оставшиеся классы-обертки числовых типов: Float и Double - помимо описанного для целочисленных примитивных типов, дополнительно содержат определения следующих констант: NEGATIVE_INFINITY - отрицательная бесконечность
POSITIVE_INFINITY - положительная бесконечность
NAN - НЕ числовое значение (неопределенность, комплексное число и т.д.)
Кроме того, несколько иначе трактуется значение MIN_VALUE - вместо наименьшего значения, оно представляет минимальное положительное (строго > 0) значение, которое может быть представлено соответствующим примитивным типом и, соответственно, классом-оберткой.
Кроме классов-оберток для примитивных числовых типов, определены таковые и для остальных примитивных типов Java:
4.2. Character
Реализует интерфейс Comparable.
Из конструкторов - имеет только один, принимающий char в качестве параметра.
Кроме стандартных методов equals(), HASHCODE(), TOSTRING() еще из НЕ статических, содержит только два метода: public char CHARVALUE() - возвращает обернутое значение char public int COMPARETO(Character ANOTHERCHARACTER) - сравнивает обернутые значения char как числа, то есть возвращает значение return this.value - ANOTHERCHARACTER.value;
Также, для совместимости с интерфейсом Comparable, метод COMPARETO() определен с параметром Object: public int COMPARETO(Object o) - если переданный объект имеет тип Character, результат будет аналогичен вызову COMPARETO((Character)o), иначе будет брошено исключение CLASSCASTEXCEPTION - так-как Character можно сравнивать только с Character.
Статических методов в классе Character довольно много, все их здесь перечислять смысла не имеет. Все они могут быть довольно полезны. Большинство - это методы, принимающие char и проверяющие всевозможные свойства - является ли цифрой, буквой, буквой заглавного или строчного шрифта, может ли с него начинаться переменная в Java, и т.д. Например: public static boolean ISDIGIT(char c) - проверяет, является ли char цифрой
Программирование на Java
Rendered by www.RENDERX.com
Boolean Стр. 13 из 33 public static boolean ISLETTER(char c) - проверяет, является ли char буквой public static boolean ISDIGITORLETTER(char c) - проверяет, является ли char цифрой или буквой public static boolean ISIDENTIFIERSTART(char c) - проверяет, является ли символ подходящим для того, что бы с него начиналось наименование переменной JAVA
Эти методы возвращают значение истина или ложь, в соответствии с тем выполнен ли критерий проверки.
4.3. Boolean
Представляет класс-обертку для примитивного типа boolean.
Реализует интерфейс java.io.Serializable и во всем напоминает аналогичные классы-обертки. Для получения примитивного типа используется метод BOOLEANVALUE().
4.4. Void
Этот класс-обертка, в отличии от остальных, НЕ реализует интерфейс java.io.Serializable. Он не имеет открытого конструктора. Более того, экземпляр этого класса вообще не может быть получен. Он нужен только для получения ссылки на объект Class, соответствующий void. Эта ссылка представлена статической константой TYPE.
Делая краткое заключение по классам-оберткам, можно сказать что • каждый примитивный тип имеет соответствующий класс-обертку
• все классы-обертки могут быть сконструированы как с использованием примитивных типов, так и с использованием String, за исключением Character, который может быть сконструирован только по char
• Классы-обертки могут сравниваться с использованием метода equals()
• примитивные типы могут быть извлечены из классов-оберток с помощью соответствующего метода XXXXVALUE() (например INTVALUE())
• классы-обертки так же являются классами-утилитами, т.е. предоставляют набор статических методов для работы с примитивными типами
• классы-обертки не могут быть модифицированы
Вывод
В этой главе Вы получили представление о назначении и возможностях классов, представленных в пакете java.lang. Как Вы теперь знаете, пакет java.lang автоматически импортируется во все Java программы и содержит фундаментальные классы и интерфейсы, которые составляют основу для других пакетов Java.
Были рассмотрены все наиболее важные классы пакета java.lang: Object, Class - основные классы, представляющие объект и класс объектов;
классы-обертки (Wrapper классы) - так как многие классы работают именно с объектами, иногда бывает необходимо представлять значения примитивных типов Java в виде объектов; в таких случаях используют классы-обертки;
Math - класс, предоставляющий набор статических методов, реализующих наиболее распространенные математические функции;
String и STRINGBUFFER - классы для работы со строками;
System, Runtime, Process, CLASSLOADER, SECURITYMANAGER - системные классы, помогающие взаимодействовать с программным окружением (System, Runtime, Process), загружать классы в JVM (CLASSLOADER) и управлять безопасностью (SECURITYMANAGER);
Thread, THREADGROUP, Runnable - типы, обеспечивающие работу с потоками исполнения в Java;
Throwable, Error, Exception, RUNTIMEEXCEPTION - базовые классы для всех исключений.
Программирование на Java
Rendered by www.RENDERX.com
Стр. 29 из 33
11. Контрольные вопросы
13-1. В чем различие между следующими кусками кода: 1. String s1 = “abc”;
String s2 = new String(“abc”); boolean result = (s1==s2);
2. String s1 = new String(“abc”); String s2 = new String(“abc”); boolean result = (s1.equals(s2));
a.) Значение result в первом случае будет равно false, в то время как во втором - true. В первом случае сравниваются значения ссылок s1 и s2, во втором, проверяется, идентичны ли объекты, на которые указывают эти ссылки. При этом s1 и s2 указывают на разные объекты, так как объект s2 был получен применением оператора new, вследствие чего был создан новый объект. В случае если бы s2 был получен тем же способом, что и s1 (то есть String s2 = “abc”;), то обе ссылки s1 и s2 указывали бы на один и тот же объект, так как Java не создает новый экземпляр для строковых литералов, если таковой уже имеется. Вместо этого ссылка будет указывать на уже существующий объект.
13-2. Какие условия должны быть выполнены при переопределении метода equals()? a.) Переопределение метода equals() предполагает выполнение следующих правил: 1. a) рефлексивность: для любой объектной ссылки x, вызов x.equals(x) возвращает true
2. b) симметричность: для любых объектных ссылок x и y, вызов x.equals(y) возвращает true тогда и только тогда, если вызов y.equals(x) возвращает true
3. c) транзитивность: для любых объектных ссылок x, y и z, если x.equals(y) возвращает true и y.equals(z) возвращает true, тогда вызов x.equals(z) должен вернуть true
4. d) непротиворечивость: для любых объектных ссылок x и y, многократные последовательные вызовы x.equals(y) возвращают одно и то же значение (либо всегда true либо всегда false)
5. e) для любой не равной null объектной ссылки x, вызов x.equals(null) должен вернуть значение false
13-3. Как формально формулируются правила, которым должна следовать реализация метода HASHCODE()? Как реализован этот метод в классе Object?
Программирование на Java
Rendered by www.RENDERX.com
Стр. 30 из 33 Контрольные вопросы a.) Для реализаций метода HASHCODE() должны быть выполнены следующие правила: 1. a) в одном запуске программы, для одного объекта при вызове метода HASHCODE(), должно возвращаться одно и то же int значение, если между этими вызовами НЕ были затронуты данные, используемые для проверки объектов на идентичность в методе equals(). Это число НЕ обязано быть одним и тем же при повторном запуске той же программы, даже если все данные будут идентичны
2. b) если два объекта идентичны, то есть вызов метода equals(Object) возвращает true, тогда вызов метода HASHCODE() у каждого из этих двух объектов должен возвращать одно и то же значение
3. c) если два объекта различны, то есть вызов метода equals(Object) возвращает false, тогда различие их хеш-кодов желательно, но НЕ обязательно. Различие в хеш-кодах для НЕ идентичных объектов нужно только для обеспечения хорошей производительности при использовании этих объектов в хеш-таблицах.
В классе Object метод HASHCODE() возвращает значение адреса, где хранится объект. Такая реализация удовлетворяет всем правилам и переопределение метода HASHCODE() в подклассах Object не требуется, если не был переопределен метод equals().
13-4. Если был переопределен метод equals(), какой еще метод, возможно, понадобится переопределить соответствующим образом, чтобы объекты рассматриваемого класса могли быть корректно использованы в хэш-таблицах? a.) Среди правил, которым должна удовлетворять реализация метода HASHCODE(), есть следующее: “если два объекта идентичны, то есть вызов метода equals(Object) возвращает true, тогда вызов метода HASHCODE() у каждого из этих двух объектов должен возвращать одно и то же значение”.
Соответственно, если метод equals() был переопределен, и объекты этого класса планируется использовать в хеш-таблицах, то в соответствии с указанным правилом, метод HASHCODE() понадобится переопределить таким образом, что бы возвращались одинаковые значения для объектов, вызов метода equals() для которых возвращает true.
13-5. Как реализованы в классе Object методы equals(), TOSTRING(), HASHCODE() ? a.) В классе Object методы equals(), TOSTRING() и HASHCODE() имеют следующие реализации: equals() - возвращает true, если ссылки на объекты совпадают TOSTRING() - возвращает строку, которая составляется следующим образом: название класса, символ ‘@’, значение, возвращаемое вызовом метода HASHCODE(), представленное в шестнадцатеричном виде HASHCODE() - имеет native реализацию, возвращающую адрес, по которому хранится объект.
Програtrialвание на Java
Rendered by www.RENDERX.com
Стр. 31 из 33
13-6. Какие объекты могут быть клонированы? a.) Если клонирование производится встроенным методом Object.clone(), то такие классы необходимо специальным образом помечать, указывая, что они реализуют интерфейс Cloneable. Кроме этого, класс может переопределить метод clone() собственным образом, и обойтись без этого интерфейса.
13-7. Какие существуют ограничения на использование метода NEWINSTANCE() объектов типа Class для создания экземпляров соответствующего класса? a.) Вызов этого метода создает объект класса, который представляется данным экземпляром Class. Создание будет происходить с помощью конструктора без параметров. Соответственно, что бы создание прошло успешно, такой конструктор должен иметься в классе, а сам класс не должен быть абстрактным.
13-8. Для каких примитивных типов Java существуют классы-обертки? Что будет получено в результате выполнения: (new Integer(1)).equals(new Byte(1)) ? a.) Классы-обертки существуют для всех примитивных типов Java - byte, short, char, int, long, float, double, boolean (обертка существуют даже для «отсутствия типа» - void).
Вызов (new Integer(1)).equals(new Byte(1)) вернет значение false, так как метод equals() в классах-обертках реализован таким образом, что сначала производится сравнение классов сравниваемых объектов, и если они не совпадают - возвращается значение false.
13-9. В чем особенность класса-обертки для void? a.) Этот класс, в отличие от остальных классов-оберток, НЕ реализует интерфейс java.io.Serializable. Он не имеет открытого конструктора. Более того, экземпляр этого класса вообще не может быть получен.
13-10. Какие модификаторы присутствуют в определении класса Math? Можно ли от него наследоваться? Можно ли создавать экземпляры этого класса? a.) Класс Math определен с модификаторами public и final. Соответственно, наследование от класса Math не возможно. Кроме того, единственный конструктор этого класса имеет модификатор доступа private и поэтому может быть вызван только из самого класса Math (впрочем, в классе Math нигде нет вызова этого конструктора). Все методы этого класса - статические.
13-11. В чем проявляется сходство String и примитивных типов Java? a.) Во-первых, для объектов только этого типа существуют соответствующие литералы, которыми можно инициализировать их значения. Во-вторых, только для одного ссылочного типа String определен оператор “ ”.
Кроме того, поскольку класс String является final, String-переменные всегда хранят значения точно такого же типа. Объекты класса String являются
Программирование на Java
Rendered by www.RENDERX.com
Стр. 32 из 33 Контрольные вопросы неизменяемыми, поэтому значение переменной не может измениться, если ее передать в качестве аргумента при вызове метода.
13-12. Какой класс используется для представления модифицируемых строк? a.) Если класс String представляет НЕ модифицируемые строки, то класс STRINGBUFFER позволяет изменять значение строки, которую его объект содержит.
13-13. Какие классы и интерфейсы, необходимые для поддержки многопоточности, определены в пакете java.lang? a.) Основной класс для обеспечения многопоточности - java.lang.Thread, объекты которого соответствуют потокам. Потоки могут быть объединены в группы потоков, что представляется объектами класса java.lang.THREADGROUP. Создать новый поток можно, унаследовав класс от Thread, либо реализовав интерфейс Runnable.
13-14. Классы каких базовых исключений определены в пакете java.lang ? a.) Все классы базовых исключений содержатся в пакете java.lang - Throwable, Error, Exception, RUNTIMEEXCEPTION.
Программирование на Java
Rendered by www.RENDERX.com
Вы можете ЗАГРУЗИТЬ и ПОВЫСИТЬ уникальность своей работы