410013796724260
• Webmoney
R335386147728
Z369087728698
Пакет java.langПакет java.lang является наиболее важным из всех пакетов, входящих в Java API, поскольку включает классы, составляющие основу для всех других классов. Каждый класс в Java неявным образом импортирует все классы данного пакета, поэтому данный пакет можно не импортировать. В этой библиотеке включены
ObjectОснову пакета составляет класс Object, который является корневым в иерархии классов. Если при описании класса родитель не указывается, то им считается класс Object. Все объекты, включая массивы, наследуются от этого класса. Класс Object включает методы, которые наследуются остальными классами Java.
Методы notify(), notifyAll(), wait() используются для поддержки многопоточности и являются "финальными" (final), т.е. их нельзя переопределять в классах-наследниках. Также нельзя переопределять и метод getClass. Метод equalsОсобый интерес представляет метод equals, определяющий, являются ли объекты одинаковыми. В классах - наследниках, этот метод при необходимости может быть переопределен, чтобы отражать действительное равенство объектов. Например, сравнение объектов-оберток целых чисел (класс Integer), должно по всей логике возвращать значение true, если равны значения int чисел, которые обернуты, даже если различаются объектные ссылки на сами объекты класса-обертки Integer. Пример использования метода equals package example; public class Rectangle { public int sideA; public int sideB; public Rectangle(int x, int y) { super(); sideA = x; sideB = y; } public boolean equals(Object obj) { if(!(obj instanceof Rectangle)) return false; Rectangle ref = (Rectangle)obj; return (((this.sideA == ref.sideA) && (this.sideB == ref.sideB)) || (this.sideA == ref.sideB) && (this.sideB==ref.sideA)); } public static void main(String[] args) { Rectangle r1 = new Rectangle(10,20); Rectangle r2 = new Rectangle(10,10); Rectangle r3 = new Rectangle(20,10); System.out.println("r1.equals(r1) == "+r1.equals(r1)); System.out.println("r1.equals(r2) == "+r1.equals(r2)); System.out.println("r1.equals(r3) == "+r1.equals(r3)); System.out.println("r2.equals(r3) == "+r2.equals(r3)); System.out.println("r1.equals(null)=="+r1.equals(null)); } } В этом примере метод equals класса Retangle переопределен таким образом, чтобы прямоугольники были равны, если соблюдается геометрическое равенство, т.е. их можно наложить друг на друга. Выполнение программы выведет в консоль следующее сообщение : r1.equals(r1) == true r1.equals(r2) == false r1.equals(r3) == true r2.equals(r3) == false r1.equals(null) == false Дополнительно об equals можно прочитать здесь. Метод finalizeМетод protected void finalize() throws Throwable - вызывается Java-машиной перед тем, как сборщик мусора (garbage collection) очистит память, занимаемую объектом. Объект «входит в сферу интересов» сборщика мусора, когда в выполняющейся программе не будет ни одной ссылки на объект. Перед очисткой занимаемой объектом памяти, будет вызван его метод finalize(). Реализация метода finalize в классе Object не включает кода, т.е. не выполняет каких-либо действий. В классах-наследниках этот метод может быть переопределен для проведения всех необходимых действий по освобождению различных занимаемых ресурсов - закрытия сетевых соединений, файлов и т.д. Метод getClassМетод public final native Class getClass() возвращает объект типа Class, соответствующий классу объекта. Метод hashCodeФункция hashCode возвращает хеш (hash code) объекта. Хеш-код представляет собой целое число, которое с большой вероятностью является уникальным для объекта. Данное значение используется коллекцией Hashtable для хранения данных с возможностью быстрой выборки объекта. Обычно метод hashCode не переопределяется. Но, если же, придется это сделать, то необходимо убедиться, чтобы метод возвращал одно и то же значение для равных между собой объектов. То есть, если x.equals(y) возвращает true, то зачения хеш-кодов x и y должны совпадать, то есть вызовы x.hashCode() и y.hashCode() должны возвращать одно и то же значение. В противном случае Hashtable будет считать объекты различными, не вызывая метод equals(). Дополнительно о hashCode можно прочитать здесь. Метод toStringМетод toString возвращает строковое представление объекта. В классе Object этот метод реализован следующим образом : public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } То есть, метод toString возвращает строку, содержащую название класса объекта и его хеш-код. В классах-наследниках этот метод может быть переопределен для получения более наглядного пользовательского представления объекта. Так для представленного выше примера Rectangle метод toString мог бы выглядеть следующим образом : @Override public String toString() { return getClass().getName() + "{ sideA = " + String.value (sideA) + ", sideB = " + String.value (sideB) + " }"); } Метод cloneМетод protected native Object clone() throws CloneNotSupportedException создает копию объекта. Для того, чтобы использовать данный метод, объект должен реализовывать интерфейс Cloneable, который не определяет никаких методов. Реализация интерфейса Cloneable только символизирует, что можно создавать копии объектов этого класса. В классе Object метод clone реализован таким образом, что копируются только базовые типы и ссылки на объекты. Если же потребуется «полное» копирование, то есть копирование не только ссылок на объекты, но и создание копии объектов, то в классах-наследниках метод clone нужно переопределить. Рассмотрим простой пример CloneTest.java, включающий 4 поля - целочисленный id, текстовую date, корзину basket типа List и свойство props типа HashMap. В классе реализованы методы Get/Set, и, кроме этого, класс включает методы addGoods, addGood для добавления товара списком и по отдельности. Определенные строки кода содержат строчные комментарии и будут рассмотрены ниже. package example; // import java.io.IOException; // import java.io.ByteArrayInputStream; // import java.io.ByteArrayOutputStream; // import java.io.Serializable; // import java.io.ObjectInputStream; // import java.io.ObjectOutputStream; import java.util.List; import java.util.Arrays; import java.util.HashMap; import java.util.ArrayList; public class CloneTest implements Cloneable // , Serializable { // private static final long serialVersionUID = 1L; private int id ; private String date ; private List<String> basket; private HashMap<Integer, String> props ; public CloneTest() { basket = new ArrayList<String>(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public List<String> getBasket() { return basket; } public void setBasket(List<String> basket) { this.basket = basket; } public HashMap<Integer, String> getProps() { return props; } public void setProps(HashMap<Integer, String> props) { this.props = props; } public void addGoods(final String[] list) { basket.addAll(Arrays.asList(list)); HashMap<Integer, String> hm; hm = new HashMap<Integer, String>(); for (int i = 0; i < list.length; i++) hm.put(Integer.valueOf(i + 1), list[i]); setProps(hm); } public void addGood(final String good) { basket.add(good); props.put(Integer.valueOf(props.size() + 1), good); } // @Override // public Object clone() throws CloneNotSupportedException // { // // Клонируемый объект // CloneTest obj = null; // try { // ByteArrayOutputStream bos; // ObjectOutputStream ous; // bos = new ByteArrayOutputStream(); // ous = new ObjectOutputStream(bos); // // Сохраняем объект в поток // ous.writeObject(this); // ous.close(); // ByteArrayInputStream bis; // ObjectInputStream ois; // bis = new ByteArrayInputStream(bos.toByteArray()); // ois = new ObjectInputStream(bis); // // Создаем новый объек из потока // obj = (CloneTest) ois.readObject(); // } catch (IOException e) { // } catch (ClassNotFoundException e) {} // return obj; // } public static void main(String[] args) { CloneTest ct1 = new CloneTest(); CloneTest ct2 = null; ct1.setId(1); ct1.setDate("01.12.2015"); String[] goods = {"Картофель", "Свекла"}; ct1.addGoods(goods); // Используем стандартную реализацию метода clone() try { ct2 = (CloneTest) ct1.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } // Добавляем во второй объект ct2.addGood("Морковь"); // Проверяем атрибуты ct1 и ct2 на равенство System.out.println("ct1 = " + ct1.toString()); System.out.println("ct2 = " + ct2.toString()); System.out.println(); ct2.setId(2); System.out.println("ct2.id = " + ct2.getId()); System.out.println("ct1.id == ct2.id : " + (ct1.getId() == ct2.getId())); System.out.println(); System.out.println("ct2.date = " + ct2.getDate()); System.out.println("ct1.date == ct2.date : " + (ct1.getDate().equals(ct2.getDate()))); System.out.println(); System.out.println("ct1.basket : " + (ct1.basket)); System.out.println("ct2.basket : " + (ct2.basket)); System.out.println(); System.out.println("ct1.props : " + (ct1.props)); System.out.println("ct2.props : " + (ct2.props)); } } В методе main создается объект ct1 и значения его полей инициализируются. После этого создается клон объекта ct2, в который заносится товар «Морковь», изменяется идентификатор, и информация об объектах выводится в консоль : ct1 = example.CloneTest@1e859c0 ct2 = example.CloneTest@15c7850 ct2.id = 2 ct1.id == ct2.id : true ct2.date = 01.12.2015 ct1.date == ct2.date : true ct1.basket : [Картофель, Свекла, Морковь] ct2.basket : [Картофель, Свекла, Морковь] ct1.props : {1=Картофель, 2=Свекла, 3=Морковь} ct2.props : {1=Картофель, 2=Свекла, 3=Морковь} Результаты показывают, что объекты разные (первые две строчки). Но вот измененный идентификатор ct2 равен идентификатору ct1. Кроме этого «Морковь», добавленная в ct2, присутствует и в ct1. То есть, встроенный метод clone копирует ссылки на внутренние объекты. Поэтому изменение значения одного из полей затрагивает оба объекта. Если же необходимо получить новый независимый объект, соответствующий исходному, то нужно должным образом переопределить метод clone. Наиболее удобным и гибким способом клонирования объекта является механизм сериализации. Он сохраняет объект в поток байтов с последующим его восстановлением из потока. Для решения данной задачи, необходимо только убрать строчные комментарии и запустить пример на исполнение. Результат говорит сам за себя : значения идентификаторов отличаются, как и отличается содержимое корзины. ct1 = example.CloneTest@a470b8 ct2 = example.CloneTest@1975b59 ct2.id = 2 ct1.id == ct2.id : false ct2.date = 01.12.2015 ct1.date == ct2.date : true ct1.basket : [Картофель, Свекла] ct2.basket : [Картофель, Свекла, Морковь] ct1.props : {1=Картофель, 2=Свекла} ct2.props : {1=Картофель, 2=Свекла, 3=Морковь} Таким образом, сериализация является наиболее предпочтительным вариантом для получения независимого клонированного объекта. ClassВ исполняемой java-программе каждому классу соответствует объект типа Class, который содержит необходимую для описания класса информацию (поля, методы и т.д.). Класс Class не имеет открытого конструктора – объекты этого класса создаются автоматически Java-машиной по мере загрузки классов и вызовов метода defineClass загрузчика классов. Получить экземпляр Class для конкретного класса можно воспользовавшись перегруженным методом forName : public static Class forName (String name, boolean initialize, ClassLoader loader); public static Class forName(String className); Метод forName возвращает объект Class, соответствующий классу или интерфейсу с названием, указанным в name. Необходимо указывать полное название класса или интерфейса (наименование пакета и наименование класса), используя переданный загрузчик классов. Если в качестве загрузчика классов loader передано значение null, будет применен тот загрузчик, который использовался для загрузки вызывающего класса. При этом класс будет инициализирован, только если значение initialize равно true и класс не был инициализирован ранее. Проще и удобнее воспользоваться методом forName(className), передав только название класса. При этом будет использоваться загрузчик вызывающего класса, и класс будет инициализирован, если до этого не был. Метод public Object newInstance() создает и возвращает объект класса, который представляется данным экземпляром Class. При создании используется конструктор без параметров. Если класс не содержит такого конструктора, то будет вызвано исключение InstantiationException. Это же исключение будет брошено, если объект Class соответствует абстрактному классу, интерфейсу или же по какой-либо другой причине. Каждому методу, полю, конструктору класса также соответствуют объекты, которые можно получить вызовом следующих методов объекта Class : getMethods(), getFields(), getConstructors(), getDeclaredMethods() и т.д. Данные методы возвращают объекты, которые отвечают за поля, методы, конструкторы объекта. Их используют для формирования динамических вызовов Java. Такой процесс называется рефлексией кода (reflection). Классы, используемые в reflection содержатся в пакете java.lang.reflection. Пример работы с объектом ClassДинамическое создание экземпляров не обязательно всегда сопровождается вызовом методов посредством reflection. Это продемонстрировано в следующем примере : package example; interface Vehicle { void go(); } class Automobile implements Vehicle { public void go() { System.out.println("\tавтомобиль поехал!"); } } class Truck implements Vehicle { public Truck(int i) { super(); } public void go() { System.out.println("\tгрузовик поехал!"); } } public class ClassExample { public static void main(String[] args) { Vehicle vehicle; String[] vehicleNames = {"example.Automobile", "example.Truck" , "example.Aircraft"}; for(int i = 0; i < vehicleNames.length; i++){ try { String name = vehicleNames[i]; System.out.println("Class : " + name); Class<?> aClass = Class.forName(name); System.out.println("\tсоздание автомобиля ..."); vehicle = (Vehicle)aClass.newInstance(); System.out.println("\tnewInstance : " + vehicle.getClass()); vehicle.go(); } catch(ClassNotFoundException e){ System.out.println(e.toString()); } catch(InstantiationException e){ System.out.println(e.toString()); } catch(Throwable th){ System.out.println("Throwable : " + th.toString()); } } } } В консоль будет выведено следующее сообщение : Class : example.Automobile создание автомобиля ... newInstance : class example.Automobile автомобиль поехал! Class : example.Truck создание автомобиля ... java.lang.InstantiationException: example.Truck Class : example.Aircraft java.lang.ClassNotFoundException: example.Aircraft Как видим из текста сообщения, объект класса Automobile был успешно создан, получен его экземляр Instance, определенный интерфейсом Vehicle, и вызван метод go. Класс Truck был найден, но при создании объекта этого класса, вызывается отсутствующий в описании конструктор без параметров, вследствие чего было выброшено и обработано исключение java.lang.InstantiationException. Этого можно было бы избежать, если бы в описание класса Truck был бы включен пустой конструктор public Truck() {}. Класс example.Aircraft не был определен, и при попытке получить соответствующий данному объекту Class, было вызвано исключение java.lang.ClassNotFoundException. MathКласс Math состоит из набора статических методов, выполняющих наиболее популярные математические вычисления, и двух констант, имеющих особое значение в математике - это число Пи и экспонента. Константы определены следующим образом :
Часто класс Math называют классом-утилитой (Utility class), т.к. все методы класса статические и нет необходимости создавать экземпляр этого класса - поэтому он и не имеет открытого конструктора. Этот класс нельзя также и унаследовать, поскольку он объявлен с атрибутом final. Методы класса Math
StringКласс String используется в Java для хранения и представления не модифицируемых строк. После того как создан экземпляр этого класса, строка уже не может быть модифицирована. Для создания объекта String можно использовать различные варианты конструктора. Наиболее простой - если содержимое строки известно на этапе компиляции - это использовать один из следующих подходов : String abc = "abc"; String cde = new String("cde"); На первый взгляд, эти варианты создания строк отличаются только синтаксисом. На самом деле различие есть, хотя в большинстве случаев его можно и не заметить. Каждый строковый литерал имеет внутреннее представление, как экземпляр класса String. Классы в JAVA могут иметь целый набор таких строк и, когда класс компилируется, экземпляр представляющий литерал, добавляется в этот набор. Однако, если такой литерал уже имеется где-то в другом месте класса, т.е. уже представлен в наборе строковых объектов, то новый экземпляр (фактически копирующий уже существующий) создан не будет. Вместо этого будет создана ссылка на уже имеющийся объект. Т.к. строки не являются модифицируемыми объектами, то это не нанесет никакого урона другим фрагментам программы. С другой стороны, если объект-строка создается с помощью явного вызова конструктора, то даже если эти строки будут совершенно идентичными, экземпляры класса String будут отличаться. В объекте String определен метод equals() который сравнивает две строки на предмет идентичности. В следующем примере сравниваются две строковых переменных с одинаковыми значениями. public class StringTest { public StringTest() {} public static void main(String[] args) { Test t = new Test(); String s1 = "Hello world"; String s2 = "Hello world"; System.out.println("String`s equally = " + (s1.equals(s2))); System.out.println("Strings are the same = " + (s1 == s2)); } } В консоль будет выведено следующее сообщение : String`s equally = true Strings are the same = true Но вот, если строку определения переменной s2 определить следующим образом : String s2 = new String("Hello world"); то сообщение в консоле изменится : String`s equally = true Strings are the same = false При первом варианте для создания двух строк используются строковые литералы, поэтому ссылки s1 и s2 ссылаются на один и тот же объект. Во втором случае для строки s2 используется конструктор. Поэтому, несмотря на то, что строки идентичны, переменные ссылаются на разные объекты, которые, в сущности, создаются во время выполнения программы и не находятся во множестве строковых констант, которое создается на момент компиляции. Необходимо отметить, что при создании экземпляров строк во время выполнения (run-time), они не помещаются в набор строковых констант. Однако, можно явно указать на необходимость поместить, вновь создаваемый экземпляр класса String в этот набор, применив метод intern(), т.е. если определить строку s2 следующим образом : String s2 = new String("Hello world!!!").intern(); то в консоль будет выведено первое сообщение. Если все строки находятся в наборе, сформированном при компиляции, то для сравнения строк, вместо метода equals() можно использовать оператор '==', который выполняется значительно быстрее. В JAVA для конкатенация строк можно использовать оператор '+' и метод String concat(String s). Следует обратить внимание на то, что строки являются не модифицируемыми объектами. И если используется оператор конкатенации или какой-либо вспомогательный метод класса String, то изменения строки не произойдет, а будет создан новый экземпляр класса String. Также следует обратить на использование в методах параметров типа String. Несмотря на то, что String является объектом и передается в метод по ссылке, String не модифицируемый объект и все изменения в методе не повлекут изменений исходного объекта. Метод trim() класса String позволяет удалить пробелы в строке, расположенные в начале и в конце строки. Помните, что после выполнения операций trim и concat создается новый объект. Строка состоит из шестнадцатибитовых UNICODE символов. Однако во многих случаях требуется работать с восьмибитовыми символами (ввод/вывод, работа с базой данных и т.д.). Преобразование строки в последовательность байтов (восьмибитовые символы) производится методами :
Оператор '+' для класса String переопределен. Так если оператор '+' применить к экземплярам класса String, то будет осуществлена конкатенация строк и, если один из операндов не принадлежит классу String (не первый), то он будет неявно приведен к этому типу, как будто бы был использован метод String.valueOf(). Например : System.out.println("1" + 5) выведет на консоль 15 System.out.println(1 + 5) выведет на консоль 6 StringBufferКласс StringBuffer используется для создания и модификации строковых выражений, из которых можно создать String. В отличии от неизменяемого String он реализован на основе массива char[] и, после создания объекта, значение содержащейся в нем строки может быть изменено. Наиболее часто используемые конструкторы класса StringBuffer :
Определение размера массива не означает, что нельзя будет манипулировать со строками, размер которых более указанной при создании объекта. Это всего лишь говорит о том, что при манипулировании строками, длина которых меньше указанной, не потребуется выделения дополнительной памяти. Пример использования StringBufferpackage example; public class StringBufferExample { void addString(StringBuffer sb, final String text) { sb.append(text); } public static void main(String[] args) { StringBuffer sb = new StringBuffer("Привет"); System.out.println("До : '" + sb + "'"); StringBufferExample sbe = new StringBufferExample(); sbe.addString(sb, " мир!"); System.out.println("После : '" + sb.toString() + "'"); } } В результате в консоль будет выведено следующее сообщение : До : 'Привет' После : 'Привет мир!' Основные методы, используемые для модификации StringBuffer /** * Метод добавления строки str к уже имеющейся в объекте */ append(String str) /** * Метод вставки строки str начиная с позиции offset (пропуская offset символов) */ insert(int offset, String str) SystemКласс System содержит набор полезных статических методов и полей. Экземпляр этого класса получить нельзя. Среди прочих полезных средств, предоставляемых классом System, особо стоит отметить
Наиболее широко используемым является стандартный вывод, доступный через переменную System.out. Стандартный вывод можно перенаправить в другой поток (файл, массив байт и т.д., главное, что бы это был объект PrintStream). Следующий код демонстрирует использование класса System : public static void main(String[] args) { System.out.println("Описание Java"); try { PrintStream print = new PrintStream( new FileOutputStream("с:/system-out.txt")); System.setOut(print); System.out.println("Изучение Java"); } catch(FileNotFoundException e) { e.printStackTrace(); } } При запуске этого кода, в консоль будет выведено только Описание Java И в файл "с:/system-out.txt" будет записано «Изучение Java». Аналогичным образом можно перенаправить стандартный ввод System.in вызовом System.setIn(InputStream) и System.err - вызовом System.setErr(PrintStream). Потоки ввода/вывода можно закрыть. Для этого следует использовать следующий код : try { System.in.close(); System.out.close(); } catch (IOException e) { e.printStackTrace(); } Следующие методы класса System позволяют использовать некоторые параметры системы :
|