что такое статический импорт какие элементы можно импортировать при статическом импорте

Блог только про Java

Учимся программировать на Java с нуля

Статический импорт в языке Java

что такое статический импорт какие элементы можно импортировать при статическом импорте. Смотреть фото что такое статический импорт какие элементы можно импортировать при статическом импорте. Смотреть картинку что такое статический импорт какие элементы можно импортировать при статическом импорте. Картинка про что такое статический импорт какие элементы можно импортировать при статическом импорте. Фото что такое статический импорт какие элементы можно импортировать при статическом импорте

В Java имеется языковое средство, расширяющее возможности ключевого сло­ва import и называемое статическим импортом.

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

Это упрощает и сокращает синтаксис, требующийся для работы со статическими членами.

Чтобы стала понятнее польза от статического импорта, начнем с примера, в котором он не используется. В приведенной ниже программе вычисляется гипо­тенуза прямоугольного треугольника. С этой целью вызываются два статических метода из встроенного в java класса Math, входящего в пакет java.lang.

Как показывает данный простой пример, очень неудобно указывать каждый раз имя класса при вызове методов pow() и sqrt() или любых других встроенныхв Java методов, выполняющих математические операции наподобие sin(), cos() и tan().

У популярного хостинга Eurobyte.ru есть свой API для Java где предоставляется класс, которого можно импортировать с помощью статического импорта. Подробнее сможете узнать на www.eurobyte.ru/services/license/bitrix_expert/, доступна детальная документация.

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

В этой версии программы имена методов sqrt() и pow() становятся видимыми ­благодаря оператору статического импорта, как показано ниже.

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

Как видите, эта форма нетолько упрощает код, но и делает его более удобочитаемым:

Имеются две основные формы оператора import static. Первая форма, упо­треблявшаяся в предыдущем примере программы, делает видимым единственное имя. В общем виде эта форма статического импорта такова:

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

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

Так, в предыдущем примере программы с помощью единственного оператора import можно сделать доступными мето­ды pow() и sqrt(), а также все осталъные статические члены класса Math, как показано ниже.

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

Разумеется, статический импорт не ограничивается только классом Math или его методами. Например, в следующей строке становится доступным статическое поле System.out.

После этого оператора данные можно выводить на консоль, не уточняя стандартный поток вывода out именем его класса System, как показано ниже.

Тем не менее приведенный выше способ импорта стандартного потока вывода System.оut столь же удобен, сколь и полемичен.

Несмотря на то что такой способ сокращает исходный текст программы, тем, кто его читает, не вполне очевидно, что out обозначает System.out.

Следует также иметь в виду, что, помимо импор­та статических членов классов и интерфейсов, определенных в прикладном про­граммном интерфейсе Jаva API, импортировать статическим способом можно так-же статические члены своих собственных классов и интерфейсов.

Каким бы удобным ни был статический импорт, очень важно не злоупотре­блять им. Не следует забывать, что библиотечные классы Java объединяются в пакеты для того, чтобы избежать конфликтов пространств имен и непреднамеренного сокрытия прочих имен.

Если статический член используется в прикладной программе только один или два раза, то его лучше не импортировать. К тому-же некоторые статические имена, как, например, System.out, настолько привычны и узнаваемы, что их вряд ли стоит вообще импортировать.

Статический импорт следует оставить на тот случай, если статические члены применяются многократно, как, например, при выполнении целого ряда математических вычислений.

В сущности, этим языковым средством стоит пользоваться, но только не злоупотреблять им.

Интересное видео по теме:

Источник

Статический импорт

В J2SE 5 появилось новое средство Java — статический импорт, что расширяет возможности ключевого слова import, import с предшествующим ключевым словом static может применяться для импорта статических членов класса или интерфейса. При использовании статического импорта появляется возможность ссылаться на статические члены непосредственно по именам, без необходимости квалифицировать их именем класса. Это упрощает и сокращает синтаксис, необходимый для работы со статическими членами.

Чтобы понять удобство статического импорта, давайте начнем с примера, который не использует его. Следующая программа вычисляет гипотенузу прямоугольного треугольника. Она использует два статических метода из встроенного Java-класса Math, входящего в пакет java.lang. Первый из них — Math.pow() — возвращает значение, возведенное в указанную степень. Второй — Math.sqrt () — возвращает квадратный корень аргумента.

Поскольку pow () и sqrt () — статические методы, они должны быть вызваны с указанием имени их класса — Math. Это приводит к следующему громоздкому вычислению гипотенузы:

hypot = Math.sqrt(Math.pow(sidel, 2) + Math.pow(side2, 2));

Как иллюстрирует этот простой пример, необходимость каждый раз специфицировать имя класса при вызовах pow () и sqrt () (или любых других математических методов Java вроде sin (), cos () и tan ()) довольно утомительно.

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

// Применение статического импорта, делающего sqrt() и pow () видимыми.
import static Java.lang.Math.sqrt;
import static Java.lang.Math.pow;
// Вычисление гипотенузы прямоугольного треугольника.
class Hypot <
public static void main(String args[]) <
double sidel, side2;
double hypot;
sidel = 3.0;
side2 = 4.0;
// Здесь sqrt() npow() можно вызывать
// непосредственно, без их имени класса.
hypot = sqrt(pow(sidel, 2) + pow(side2, 2));
System.out.println(«Даны длины сторон » + sidel + » и » + side2 + » гипотенуза равна » + hypot) ;
>
>

В этой версии имена sqrt и pow становятся видимыми благодаря оператору статического импорта:

import static java.lang.Math.sqrt;
import static java.lang.Math.pow;

После этих операторов больше нет необходимости квалифицировать pow () и sqrt () именем их класса. Таким образом, вычисление гипотенузы может быть выражено более удобно:

hypot = sqrt(pow(sidel, 2) + pow(side2, 2));

Как видите, эта форма и более читабельна.

Существуют две основных формы оператора import static. Первая, которая использовалась в предыдущем примере, делает видимым единственное имя. Его общая форма такова:

import static pkg.type-name.static-member-name;

Здесь type-name — имя класса или интерфейса, который содержит требуемый статический член. Полное имя его пакета указано в ркд, а имя члена — в static-member-name.

Вторая форма статического импорта позволяет импортировать все статические члены данного класса или интерфейса. Его общая форма показана ниже.

import static pkg.type-name.*;

Если вы будете использовать много статических методов или полей, определенных в классе, то эта форма позволит вам сделать их видимыми без необходимости специфицировать каждый отдельно. Таким образом, в предыдущей программе с помощью единственного оператора import можно ввести в область видимости pow () и sqrt () (а также все другие статические члены Math):

import static java.lang.Math.*;

Конечно же, статический импорт не ограничивается только классом Math или его методами. Например, следующая строка вводит в область видимости статическое поле System.out:

import static java.lang.System.out;

После этого оператора вы можете выводить информацию на консоль потоком out, не квалифицируя его System, как показано здесь:

out.println(«Импортировав System.out, вы можете использовать его непосредственно.»);

Однако импортировать System, out, как показано выше — это не только хорошая идея, но и предмет обсуждения. Несмотря на то что это сокращает текст программы, все же теперь не будет очевидно тем, кто читает программу, что out ссылается на System.out.

Еще один момент: в дополнение к импорту статических членов классов и интерфейсов, определенных в Java API, вы можете также использовать статический импорт для импортирования статических членов ваших собственных классов и интерфейсов.

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

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

Источник

Пакеты классов, package

Пакет package позволяет логически объединить классы в наборы. Основные классы java входят в пакет java.lang. Различные вспомогательные классы располагаются в пакете в java.util. Классы для ввода и вывода входят в пакет java.io, а классы для работы в сети – в java.net. Некоторые их этих пакетов содержат подпакеты. Так, например, java.lang содержит два специализированных пакета java.lang.reflect и java.lang.ref, а java.util содержит подпакет java.util.zip, который включает классы для работы с ZIPархивами.

Каждый класс имеет как простое имя, данное ему в определении, так и полное имя, включающее имя пакета, в который он входит. Например, класс String является частью пакета java.lang, а его полное имя – java.lang.String.

Структура пакетов в точности отображает структуру файловой системы. Все файлы с исходными кодами (java-класс) и байт-кодами (расширением class), образующие один пакет, хранятся в одном каталоге файловой системы. Подпакеты образуют подкаталоги этого каталога. Каждый пакет создает единое пространство имен namespace. Это означает, что все имена классов и интерфейсов в пакете должны быть уникальны. Имена в разных пакетах могут совпадать, но это будут разные программные модули. Организация классов в виде пакетов позволяет избежать конфликта имен между классами. В пакете дублирование имен классов не допускается. Принадлежность класса к пакету позволяет гарантировать однозначность имен.

Чтобы указать, что класс принадлежит определенному пакету, следует использовать директиву package, после которой указывается наименование (путь) пакета :

В данном примере класс HelloWorld располагается в пакете company.common. Физически это директория «$/company/common». При создании класса в среде разработки IDE (например, Eclipse) следует указать наименование пакета, тогда IDE самостоятельно при необходимости создаст каталог на жестком диске и разместит новый класс в этом каталоге.

Можно package в классе не определять. В этом случае класс будет находиться в пакете по умолчанию, который не имеет имени «$», т.е. класс будет располагаться в корневой директории исходных кодов проекта.

Наименование пакета может быть любым, но необходимо соблюдать его уникальность в проекте. Соглашение «Code Conventions» рекомендует записывать имена пакетов строчными буквами. Тогда они не будут совпадать с именами классов, которые, по соглашению, начинаются с прописной буквы.

Стандартная библиотека Java API включает сотни классов. Каждый программист в ходе работы создает десятки своих классов. Множество классов быстро увеличивается. Java позволяет отдельные классы, решающие определенную задачу (или несколько задач), объединять в библиотеки классов в виде архивов jar. Но эти библиотеки классов, кроме стандартных, не являются частью языка java.

Импорт пакетов и классов, import

Для использования класса в приложении, его следует подключить. Так расположенный в пакете java.util класс Scanner можно подключить следующим способом :

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

Директива import указывается в самом начале кода, после чего идет имя подключаемого класса (класс Scanner в примере).

В примере был подключен только один класс. Однако пакет java.util содержит большое количество разных классов. И чтобы не подключать по отдельности каждый класс, можно сразу подключить весь пакет :

Теперь можно использовать любой класс из пакета java.util.

Возможна ситуация, когда используется два класса с одинаковым наименованием, но из разных пакетов. Это относится, например, к классам Date, которые имеются в пакете java.util и в пакете java.sql, или классам List пакетов java.util и java.awt. И если необходимо одновременно использовать оба эти класса, то необходимо указывать полный путь к классам в пакете :

Следует сказать, что основные классы из пакета java.lang (например, String) подключаются автоматически и не требуют «импортирования».

Статический импорт классов, import static

В java можно использовать статический импорт. Для этого вместе с директивой import используется модификатор static :

В примере определяется статический импорт классов System и Math, которые имеют статические методы. Определение статического импорта позволяет использовать статические методы без названия класса. В примере статическая функция sqrt(20) (можно и Math.sqrt(20)), возвращает квадратный корень числа. То же самое относится и к классу System, в котором определен статический объект out, поэтому можно его использовать без указания класса, если выполнен статический импорт класса System.

Пример использования классов разных пакетов

что такое статический импорт какие элементы можно импортировать при статическом импорте. Смотреть фото что такое статический импорт какие элементы можно импортировать при статическом импорте. Смотреть картинку что такое статический импорт какие элементы можно импортировать при статическом импорте. Картинка про что такое статический импорт какие элементы можно импортировать при статическом импорте. Фото что такое статический импорт какие элементы можно импортировать при статическом импорте

Листинг базового класса, BaseClass.java

Базовый класс включает 2 поля (id, name) и методы get/set. В конструкторе значения полей инициализируется.

Переопределенная функция toString() возвращает наименование класса и значение полей.

Листинг наследника, Inheritor.java

Класс Inheritor.java наследует свойства базового класса BaseClass.java. Поскольку классы располаются в разных пакетах, то базовый класс необходимо импортировать.

Листинг основного класса, MainPackage.java

Основной класс включает статический метод main. Поскольку данный класс не «видит» наследника, то его приходится импортировать.

Результат выполнения данной программы выводится в консоль в следующем виде :

Как видно по результату выполнения программы наименование класса включает пакет.

Говоря о полном наименовании класса следует отметить, что оно включает не только наименование пакета и наименование класса, но также и класс-загрузчик classloader. Подробно о классах-загрузчиках можно почитать здесь.

Источник

stokito on software

Эта статья была размещена на сайте sun.ru, но позже она стала недоступной. Я её вытащил из кеша поисковика и сохранил на всякий случай здесь.

Аккуратное и правильное использование import static улучшит читаемость вашего кода.

Статический импорт

Для того чтобы получить доступ к статическим членам классов, требуются указать ссылку на класс. К примеру, необходимо указать имя класса Math:

Чтобы обойти это, иногда добавляют статические методы в интерфейс и наследуются от этого интерфейса. Это плохая идея. Фактически это настолько плохая идея, что для нее есть свое название: Constant Interface Antipattern (см. Effective Java, 17 статья). Дело в том, что использование статических членов класса другим классом всего лишь деталь реализации. Когда же класс реализует интерфейс, его члены становится частью публичного АРI этого класса. Детали реализации не должны становиться публичным программным интерфейсом.

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

Однажды импортированный статический член может быть использован без указания имени класса:

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

Так когда же следует использовать статический импорт? Только в некоторых случаях! Используйте его только, если иначе вы вынуждены объявлять локальные копии констант или при неправильном использовании наследования (Constant Interface Antipattern).

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

Чрезмерное использование статического импорта может сделать вашу программу нечитаемой и тяжелой в поддержке ввиду того, что пространство имен увеличится из-за всех статических членов из вашего импорта. Тот, кто будет читать ваш код (включая вас, спустя несколько месяцев после написания кода) не будут знать какому из статически импортированных классов принадлежит тот или иной член. Импортирование всех статических методов из класса может быть частично вредно для читабельности; если вы нуждаетесь только в одном или двух методах, импортируйте их по-отдельности. Использованный умело, статический импорт может сделать вашу программу более наглядной, исключая из программного кода ненужные повторения имен классов.

Перевод Комарова Е., Дмитриев А., 24.12.2007 г.

Читайте также моё объяснение для начинающих программистов Константы, перечисления (enum), и static import’ы в Java.

Не поленитесь, и почитайте ещё несколько очень важных моих статей для начинающих программистов, студентов и джуниоров.
Также не забудьте вступить в группу IT Juniors куда я пытаюсь собирать ссылки на другие полезные статьи для вас и анонсы курсов и интернатуры в компаниях.
что такое статический импорт какие элементы можно импортировать при статическом импорте. Смотреть фото что такое статический импорт какие элементы можно импортировать при статическом импорте. Смотреть картинку что такое статический импорт какие элементы можно импортировать при статическом импорте. Картинка про что такое статический импорт какие элементы можно импортировать при статическом импорте. Фото что такое статический импорт какие элементы можно импортировать при статическом импорте

Источник

Что такое статический импорт какие элементы можно импортировать при статическом импорте

Перечисления, автоупаковка, статический импорт и аннотации

Основные навыки и понятия

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

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

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

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

С точки зрения программирования перечисления оказываются удобными в тех случаях, когда требуется определить ряд значений, обозначающих совокупность элементов. Например, с помощью перечисления можно представить набор кодов состояния (успешное завершение, ошибка, необходимость повторной попытки). Конечно, такие значения можно определить и с помощью констант типа final, но перечисления обеспечивают более структурированный подход к решению подобной задачи.

Основные положения о перечислениях

Для создания перечисления служит ключевое слово enum. Ниже приведен пример простого перечисления разных видов транспортных средств.

Идентификаторы CAR, TRUCK и так далее называются константами перечислимого типа. Каждый из них автоматически неявно объявляется как открытый (public), статический (static) член перечисления Transport. Тип этих констант соответствует типу перечисления (в данном случае — Transport). В терминологии Java подобные константы называются самотипизированными (приставка “само” означает, что в качестве типа константы принимается тип перечисления).

Определив перечисление, можно создать переменную данного типа. Но, несмотря на то, что перечисление определяется как тип класса, получить экземпляр объекта типа enum с помощью оператора new нельзя. Переменная перечислимого типа создается подобно переменной простого типа. Например, для объявления переменной tp упомянутого выше перечислимого типа Transport служит следующее выражение:

Переменная tp относится к типу Transport, и поэтому ей можно присваивать только те значения, которые определены в данном перечислении. Например, в следующей строке кода переменной tp присваивается значение AIRPLANE:

Обратите внимание на то, что идентификатор AIRPLANE полностью определяется как относящийся к типу Transport.

Для проверки равенства констант перечислимого типа служит оператор сравнения =. Например, в приведенной ниже строке кода содержимое переменной tp сравнивается с константой TRAIN,

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

Как видите, в ветвях case используются константы без полного определения имени типа. Например, вместо Transport. TRUCK указано просто TRUCK. Это допустимо потому, что перечислимый тип в выражении switch неявно определяет тип констант в ветвях case. Более того, если попытаться указать тип константы явно, при компиляции возникнет ошибка.

При отображении константы перечислимого типа, например, с помощью метода println(), выводится ее имя. Так, в результате выполнения следующего оператора отобразится имя BOAT:

Ниже приведен пример программы, демонстрирующий все особенности применения перечисления Transport.

Результат выполнения данной программы выглядит следующим образом:

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

Перечисления в Java относятся к типам классов

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

Методы values() и vaJueOf()

У всех перечислений имеются два предопределенных метода: values() и valueOf().

Ниже приведены общие формы их объявления.

Выполнение этой программы дает следующий результат:

Обратите внимание на то, что в данном примере программы для перебора массива констант, полученного с помощью метода values(), используется вариант for-each цикла for. Ради большей наглядности данного примера в его коде создается переменная allTransports, которой присваивается ссылка на массив констант перечислимого типа. Но делать это совсем не обязательно, а цикл for можно написать так, как показано ниже. В этом случае необходимость в дополнительной переменной allTransports отпадает.

Обратите также внимание на то, что значение, соответствующее имени AIRPLANE, было получено в результате вызова метода valueOf():

Как пояснялось выше, метод valueOf() возвращает значение перечислимого типа, связанное с именем константы, которое передается в виде символьной строки при вызове этого метода.

Конструкторы, методы, переменные экземпляра и перечисления

Следует иметь в виду, что каждая константа перечислимого типа является объектом этого же типа, а следовательно, в перечислении можно определить конструкторы, ввести методы и объявить переменные экземпляра. Если определить для объекта перечислимого типа enum конструктор, он будет вызываться при создании каждой константы этого типа. А каждая константа перечислимого типа позволяет вызвать любой метод, определенный в перечислении. И у каждой константы перечислимого типа имеется собственная копия любой переменной экземпляра, определенной в перечислении. Ниже приведен пример с новой версией перечисления Transport, демонстрирующий применение конструктора, переменной экземпляра и метода. Благодаря им появляется возможность определить обычную скорость передвижения различных транспортных средств.

Выполнение этой программы дает следующий результат:

Когда переменная tp объявляется в методе main(), конструктор Transport() автоматически вызывается для каждой указанной константы. Аргументы, передаваемые конструктору, указываются в скобках после имени константы, как показано ниже.

Числовые значения, передаваемые конструктору Transport() в качестве параметра s, присваиваются переменной speed. Обратите также внимание на то, что список констант перечислимого типа завершается точкой с запятой. Последней в этом списке указана константа BOAT. Точка с запятой требуется в том случае, если, помимо констант, в перечислении присутствуют и другие члены.

У каждой константы перечислимого типа имеется собственная копия переменной speed, что дает возможность выяснить скорость передвижения конкретного транспортного средства, вызвав метод getSpeed(). Например, в методе main() скорость самолета определяется при следующем вызове:

Скорость каждого транспортного средства определяется путем перебора констант перечислимого типа в цикле for. А поскольку у каждой такой константы имеется своя копия переменной speed, то значения скорости, связанные с разными константами, отличаются друг от друга. Это довольно эффективный принцип организации перечислений, но он возможен только в том случае, если перечисления реализованы в виде классов, как это сделано в Java.

В предыдущем примере использовался только один конструктор, но перечисления, как и обычные классы, допускают любое число конструкторов.

Два важных ограничения

На перечисления накладываются два ограничения. Во-первых, перечисление не может быть подклассом другого класса. И во-вторых, перечисление не может выступать в роли суперкласса. Иными словами, перечислимый тип enum нельзя расширять. Если бы это было не так, перечисления действовали бы как обычные классы. Основной же особенностью перечислений является создание констант в виде объектов того класса, в котором они были объявлены.

Наследование перечислений от класса Enum

Несмотря на то что при объявлении перечислимого типа enum нельзя указывать суперкласс, все перечисления автоматически наследуют переменные и методы от класса java.lang.Enum. В этом классе определен ряд методов, доступных для использования всеми перечислениями. И хотя большинство этих методов используются редко, тем не менее два из них иногда применяются в программах на Java. Это методы ordinal() и compareTo().

Метод ordinal() принимает значение, обозначающее положение константы перечислимого типа в списке. Это значение принято называть порядковым. Ниже приведена общая форма объявления метода ordinal().

Этот метод возвращает порядковое значение вызывающей константы. Отсчет порядковых значений начинается с нуля. Следовательно, в упоминавшемся выше перечислении Transport порядковое значение константы CAR равно нулю, константы TRUCK — 1, константы AIRPLANE — 2 И Т.Д.

Для сравнения порядковых значений двух констант в одном и том же перечислении можно воспользоваться методом compareTo(). Ниже приведена общая форма объявления этого метода.

Здесь в качестве параметра е задается константа, сравниваемая с вызывающей константой, а перед ней указывается перечислимый_тип, к которому эта константа относится. Следует иметь в виду, что вызывающая константа и константа е должны относиться к одному и тому же перечислимому типу. Так, если порядковое значение вызывающей константы оказывается меньше, чем у константы е, метод compareTo() возвращает отрицательное значение. Если же их порядковые значения совпадают, вращается нулевое значение. И наконец, если порядковое значение вызывающей константы больше, чем у константы е, метод возвращает положительное значение.

Ниже приведен пример программы, демонстрирующий применение методов ordinal() иcompareTo().

Результат выполнения данной программы выглядит следующим образом: Here are all Transport constants and their ordinal values:

Пример для опробования 12.1. Автоматизированный светофор

Перечисления оказываются полезными в тех случаях, когда в программе требуется набор констант, конкретные значения которых не важны, — достаточно, чтобы они отличались друг от друга. Необходимость в подобных наборах констант часто возникает при написании программ. Одним из характерных тому примеров служит поддержка устройств, которые могут находиться в нескольких фиксированных состояниях.Допустим, требуется программа, управляющая светофором, переключающимся в три состояния, обозначаемые зеленым, желтым и красным цветом. Необходимо также, чтобы программа могла определять текущий цвет и устанавливать светофор в исходное состояние. Таким образом, нужно как-либо представлять три возможных состояния светофора. И хотя для этой цели вполне допустимо применять целочисленные значения, например, 1, 2 и 3 или символьные строки «red» (красный), «green» (зеленый) и «yellow» (желтый), вместо них лучше всего воспользоваться перечислением. С помощью перечисления можно написать более эффективный и структурированный код, чем тот, в котором применяются символьные строки и целочисленные значения.

В этом проекте предстоит сымитировать автоматизированный светофор. А по ходу дела будет продемонстрировано применение не только перечислений, но и многопоточной обработки и синхронизации потоков.

Создайте файл TrafficLightDemo.java.

Начните с создания перечисления TrafficLightColor, которое представляет три состояния светофора.

Каждая из констант в этом перечислении соответствует одному цвету светофора.

Далее начните определение класса Traf f icLightSimulator так, как показано ниже. Этот класс инкапсулирует имитацию светофора.

Как видите, класс TrafficLightSimulator реализует интерфейс Runnable. Благодаря этому каждое состояние светофора и его цвет регулируется в отдельном потоке. Как следует из приведенного выше исходного кода, в классе TrafficLightSimulator определены два конструктора. Первый из них служит для указания исходного цвета светофора. А второй принимает в качестве исходного красный цвет. Оба конструктора запускают на исполнение новый поток.

А теперь рассмотрим переменные экземпляра. Ссылка на поток, регулирующий состояние и цвет светофора, хранится в переменной thrd. А сведения о текущем цвете хранятся в переменной tic. Переменная stop служит для остановки имитации автоматизированного светофора. Первоначально она принимает логическое значение false. Имитация светофора будет действовать до тех пор, пока эта переменная не примет логическое значение true. И наконец, переменная changed принимает логическое значение true при переключении светофора, когда его цвет меняется.

Введите приведенный ниже метод run(), начинающий имитацию автоматизированного светофора.

Этот метод переключает цвета светофора по очереди. Сначала выполнение потока приостанавливается на заданный промежуток времени, который выбирается в зависимости от конкретного цвета светофора. Затем вызывается метод changeColor(), переключающий цвет светофора.

Введите приведенный ниже метод changeColor(), переключающий цвет светофора.

В операторе switch проверяются сведения о цвете светофора, хранящиеся в переменной tic, после чего этой переменной присваивается другой цвет. Обратите внимание на то, что этот метод синхронизирован. Это необходимо потому, что он вызывает метод notify(), уведомляющий о смене цвета. (Напомним, что обратиться к методу notify() можно только из синхронизированного контекста.)

Далее введите метод wait For Change(), ожидающий переключения цвета светофора.

Действие этого метода ограничивается вызовом метода wait(). Возврат из него не произойдет до тех пор, пока в методе changeColor() не будет вызван метод notify(). Следовательно, метод waitForChange() не завершится до переключения цвета светофора.

И наконец, введите метод getColor(), возвращающий текущий цвет светофора, а вслед за ним — метод cancel(), останавливающий имитацию светофора, присваивая переменной stop логическое значение true. Ниже приведен исходный код обоих методов.

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

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

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

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

В версии JDK 5 были реализованы два очень важных языковых средства, недостаток которых долгое время ощущали программирующие на Java. Речь идет об автоупаковке и автораспаковке, существенно упрощающих и ускоряющих создание кода, в котором приходится преобразовывать простые типы данных в объекты, и наоборот. А поскольку такие потребности возникают в программах довольно часто, то появление автоупаковки и автораспаковки положительно сказалось на работе практически всех программирующих на Java. Как будет показано в главе 13, автоупаковка и автораспаковка способствовали практическому применению обобщений — еще одного языкового средства, реализованного в Java.

Автоупаковка и автораспаковка непосредственно связаны с оболочками типов и способами внедрения и извлечения значений из экземпляров оболочек. Поэтому рассмотрим сначала оболочки типов и способы упаковки и распаковки Значений вручную.

Как вам должно быть уже известно, в Java предусмотрены простые типы данных, в том числе int и double. Простые типы позволяют добиться более высокой эффективности вычислений по сравнению с объектами. Но простые типы не являются частью иерархии объектов и не наследуют свойства и методы класса Object.

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

Оболочки типов реализуются в классах Double, Float, Long, Integer, Short, Byte, Character и Boolean, входящих в пакет java. lang. Эти классы предоставляют методы, позволяющие полностью интегрировать простые типы данных в иерархию объектов Java.

Чаще всего применяются оболочки типов, представляющие числовые типы данных: Byte, Short, Integer, Long, Float и Double. Все оболочки числовых типов данных являются производными от абстрактного класса Number. В классе Number определены методы, возвращающие значение объекта для каждого числового типа данных. Эти методы перечислены ниже.

Например, метод doubleValue() возвращает значение объекта как double, метод floatValue() — как float и т.д. Перечисленные выше методы реализуются каждым классом оболочки числового типа.

В каждом классе оболочки числового типа предусмотрены конструкторы, позволяющие сформировать объект на основе соответствующего простого типа данных или его строкового представления. Например, в классах Integer и Double имеются следующие конструкторы:

Если параметр str не содержит допустимое строковое представление числового значения, генерируется исключение NumberFormatException.

Во всех оболочках типов переопределен метод toString(). Он возвращает из оболочки значение в удобной для чтения форме. Это позволяет выводить значения на экран, передавая объекты оболочек в качестве параметра методу, например println(), и не преобразуя их предварительно в простые типы данных.

Процесс инкапсуляции значения в оболочке типа называется упаковкой. До появления версии JDK 5 упаковка производилась вручную, т.е. программирующий на Java строил явным образом экземпляр класса оболочки с нужным значением. Например, для ручной упаковки значения 100 в объект типа Integer требовалась следующая строка кода:

В данном примере явно создается объект типа Integer, в который упаковывается значение 100, а ссылка на этот объект присваивается переменной iOb.

Процесс извлечения значения из объекта оболочки называется распаковкой. До появления версии JDK 5 распаковка также производилась вручную, т.е. программирующему на Java приходилось вызывать явным образом соответствующий метод для объекта оболочки, чтобы извлечь значение, упакованное в этом объекте. Например, для распаковки значения из объекта iOb вручную и присваивания результата переменной int требовалась следующая строка кода:

В данном примере метод intValue() возвращает значение, упакованное в объект iOb как int.

Рассмотренные выше механизмы упаковки и распаковки демонстрируются в приведенном ниже примере программы.

В данной программе целочисленное значение 100 упаковывается в объект типа Integer, на который ссылается переменная iOb. Для извлечения упакованного числового значения вызывается метод intValue(). Полученное значение сохраняется в переменной i. А в конце программы на экран выводятся значения переменных i и iOb, каждое из которых равно 100.

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

Основные положения о об автоупаковке

Автоупаковка — это процесс автоматической инкапсуляции (упаковки) простого типа данных в объекте оболочки соответствующего типа всякий раз, когда в этом возникает потребность, причем создавать такой объект явным образом не нужно. Автораспаковка — это процесс автоматического извлечения (распаковки) из объекта оболочки упакованного в нем значения соответствующего типа всякий раз, когда в этом возникает потребность. Благодаря автораспаковке отпадает необходимость в вызове таких методов, как intValue() и doubleValue().

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

Обратите внимание на то, что в данном примере отсутствует оператор new, конструирующий объект явным образом. Создание объекта происходит автоматически.

Для распаковки значения из объекта достаточно присвоить переменной простого типа ссылку на этот объект. Например, для распаковки значения, упакованного в объекте iOb, нужно лишь ввести в код следующую единственная строку:

А все остальное возьмет на себя исполняющая система Java. Ниже приведен пример программы, демонстрирующий автоупаковку и автораспаковку.

Автоупаковка и методы

Автоупаковка и автораспаковка происходят не только в простых операциях присваивания, но и в тех случаях, когда простой тип требуется преобразовать в объект, и наоборот. Следовательно, автоупаковка и автораспаковка могут происходить при передаче аргумента методу и при возврате значения последним. Рассмотрим в качестве примера следующую программу:

Результат выполнения данной программы выглядит так:

В объявлении метода m() указывается, что ему должен передаваться параметр типа Integer. В методе main() целочисленное значение 199 передается методу m() в качестве параметра. В итоге происходит автоупаковка этого целочисленного значения. Далее в программе вызывается метод m2 (), возвращающий целочисленное значения 10. Это значение присваивается переменной ссылки на объект iOb в методе main(). А поскольку объект iOb относится к типу Integer, то целочисленное значение, возвращаемое методом m2 (), автоматически упаковывается. Затем в методе main() вызывается метод m3 (). Он возвращает объект типа Integer, который посредством автораспаковки преобразуется в тип int. И наконец, в методе main() вызывается метод Math. sqrt(), которому в качестве аргумента передается объект iOb. В данном случае происходит автораспаковка данного объекта, а его значение продвигается к типу double, поскольку параметр именно этого типа должен быть передан методу Math. sqrt().

Автоупаковка и автораспаковка в выражениях

Автоупаковка и автораспаковка выполняются всякий раз, когда объект необходимо преобразовать в простой тип, а простой тип — в объект. Так, автораспаковка производится при вычислении выражений, и если требуется, то результат вычисления упаковывается. Рассмотрим в качестве примера приведенную ниже программу.

Выполнение этой программы дает следующий результат:

В данной программе особое внимание обратите на следующую строку кода:

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

Благодаря автораспаковке объекты оболочек целочисленных типов, например Integer, можно использовать в операторах switch. В качестве примера рассмотрим следующий фрагмент кода:

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

Как следует из приведенных выше примеров, выражения, в которых применяются объекты оболочек простых типов, становятся интуитивно понятными благодаря автоупаковке и автораспаковке. До появления версии JDK 5 для достижения аналогичного результата в программе приходилось прибегать к приведению типов и вызовам специальных методов вроде intValue().

Предупреждение относительно автоупаковки и автораспаковки

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

В данном примере в объектах типа Double хранятся три значения, используемые для вычисления арифметического среднего, а полученный результат присваивается другому объекту типа Double. И хотя такой код формально считается корректным, а следовательно, будет выполняться правильно, тем не менее, автоупаковка и автораспаковка применяются в нем совершенно не оправданно. Ведь подобный код значительно менее эффективен аналогичного кода, написанного только с использованием переменных типа double. А каждая распаковка и упаковка связана с издержками, которые простые типы не налагают на вычислительные ресурсы.

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

Начиная с версии JDK 5 в Java была расширена область применения ключевого слова import, а именно: реализован механизм статического импорта. Указав после import ключевое слово static, можно сформировать выражение для импорта статических членов класса или интерфейса. Используя статический импорт, можно также ссылаться на статические члены непосредственно по именам, не указывая перед ними имена классов. Благодаря этому упрощается синтаксис и сокращается запись выражений, в которых применяются статические члены классов.

Для того чтобы оценить по достоинству возможности статического импорта, начнем его рассмотрение с примера, в котором это языковое средство не используется. Ниже проведен пример программы для решения следующего квадратного уравнения:

В этой программе применяются два статических метода — Math.pow() и Math, sqrt() — из класса Math, который, в свою очередь, входит в пакет j ava. lang. Первый из них возвращает значение, возведенное в заданную степень, а второй — квадратный корень значения своего параметра.

Методы pow() и sqrt() являются статическими, а следовательно, их нужно вызывать, ссылаясь на имя класса Math. Их вызов осуществляется в приведенном ниже выражении, хотя и нельзя не признать, что оно получается довольно громоздким.

В таких выражениях приходится постоянно следить за тем, чтобы перед методами pow() и sqrt() (и другими подобными методами, например sin(), cos() и tan()) было указано имя класса, что неудобно и чревато ошибками.

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

В данной версии программы имена методов sqrt и pow уже не нужно указывать полностью (т.е. вместе с именем их класса). И достигается это благодаря статическому импорту обоих методов в приведенных ниже операторах, делающих оба метода непосредственно доступными.

После статического импорта отпадает необходимость предварять имена методов sqrt() и pow() именем их класса. В итоге выражение для решения квадратного уравнения принимает следующий вид:

Теперь оно выглядит проще и воспринимается намного лучше. В Java предусмотрены две общие формы оператора import static. В первой форме, использованной в предыдущем примере, непосредственно доступным для программы делается единственное имя. Йиже приведена эта общая форма статического импорта.

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

Если предполагается использовать несколько статических методов или полей, определенных в классе, то данная общая форма записи позволяет импортировать все эти члены одновременно. Таким образом, обеспечить непосредственный доступ к методам pow() и sqrt() в предыдущей версии программы (а также к другим статическим членам класса Math) без указания имени класса можно с помощью следующей единственной строки кода:

Очевидно, что статический импорт не ограничивается только классом Math и его методами. Так, если требуется сделать непосредственно доступным статическое поле System, out потока стандартного вывода, в программу достаточно ввести следующую строку кода:

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

Насколько целесообразно поступать именно так — вопрос спорный. С одной стороны, размер исходного кода в этом случае сокращается. А с другой стороны, тем, кто просматривает исходный код программы, может быть непонятно, что конкретно обозначает имя out: поток стандартного вывода System, out или нечто иное.

Каким бы удобным ни был статический импорт, важно следить за тем, чтобы он применялся правильно. Как известно, библиотеки классов Java организованы в пакеты именно для того, чтобы исключить конфликты имен. Если импортируются статические члены класса, они переносятся в глобальное пространство имен. Вследствие этого увеличивается вероятность конфликтов и неумышленного сокрытия имен. Если статический член используется в программе один или два раза, то импортировать его нет никакого смысла. Кроме того, некоторые имена статических членов (например, System, out) настолько знакомы всем программирующим на Java, что они окажутся менее узнаваемыми, если будут употребляться без имени своего класса. Статический импорт был внедрен в расчете на те программы, в которых постоянно применяются определенные статические члены, например при математических расчетах. Следовательно, статическим импортом следует пользоваться аккуратно, не злоупотребляя им.

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

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

На заметку Подробнее с метаданными и аннотациями можно ознакомиться в книге Java. Полное руководство, 8-е издание, ИД «Вильямс», 2012 г.

Для составления аннотаций служит ключевое слово interface. Ниже приведен простой пример объявления аннотации.

В данном примере объявляется аннотация MyAnno. Обратите внимание на то, что ключевое слово interface предваряется знаком @. Таким образом компилятору сообщается об объявлении аннотации. Обратите также внимание на два члена — str() и val(). Все аннотации содержат лишь объявления методов, а их тела указывать нельзя. Объявленные методы реализует исполняющая система Java, причем они действуют подобно полям.

Аннотации всех типов автоматически расширяют интерфейс Annotation. Следовательно, Annotation служит в качестве суперинтерфейса для всех аннотаций. Он входит в пакет java.lang.annotation.

Объявив аннотацию, ее можно использовать для аннотирования объявления. Аннотацию можно связать с любым объявлением. В частности, аннотированными могут быть объявления классов, методов, полей, параметров, констант перечислимого типа и даже самих аннотаций. Но в любом случае аннотация предшествует остальной части объявления.

Применяя аннотацию, вы тем самым задаете значения ее членов. Ниже приведен пример аннотации MyAnno, применяемой к методу.

Эта аннотация связывается с методом myMeth(). Обратите внимание на синтаксис аннотации. Имени аннотации предшествует знак @, а после имени следует список, предназначенный для инициализации ее членов. Для того чтобы задать значение члена аннотации, следует присвоить это значение имени данного члена. В рассматриваемом здесь примере символьная строка «Annotation Example» (Пример аннотации) присваивается члену str аннотации MyAnno. Обратите внимание на то, что в операторе присваивания скобки после члена str не указываются. При присваивании значения члену аннотации используется только его имя. В этом отношении члены аннотации похожи на поля.

Аннотация без параметров называется маркером. При определении маркера круглые скобки не указываются. Главное назначение маркера — пометить объявление некоторым атрибутом.

В Java определено немало встроенных аннотаций. Некоторые из них считаются аннотациями общего назначения, но большинство являются специализированными. В пакет java.lang.annotation входят аннотации @Retention, @Documented, @Target и @Inherited. Аннотации @Override, @Deprecated и @SuppressWarnings включены в пакет ava.lang. Назначение этих семи аннотаций приведено в табл. 12.1.

Таблица 12.1. Встроенные аннотации

АннотацияОписание
@RetentionОпределяет правила сохранения, связываемые с аннотацией. Правила сохранения определяют, как долго аннотация будет присутствовать в процессе компиляции и развертывания прикладной программы
@DocumentedМаркер, сообщающий инструментальному средству о том, что аннотация документируется. Желательно использовать только как аннотацию к аннотации объявления
@TargetЗадает виды объявлений, к которым может быть применена аннотация. Желательно использовать только в качестве одной аннотации к другой. Данная аннотация принимает аргумент в виде константы перечислимого типа ElementType, в котором определены различные константы, в том числе CONSTRUCTOR, FIELD и METHOD. Аргумент определяет виды объявлений, к которым может быть применена аннотация
@InheritedМаркер, указывающий на то, что аннотация суперкласса должна наследоваться подклассом
@OverrideМетод, аннотированный как @Override, должен переопределять метод суперкласса. Если это условие не выполняется, возникает ошибка при компиляции. Данная аннотация представляет собой маркер и позволяет убедиться в том, что метод суперкласса действительно переопределен, а неперегружен
@DeprecatedМаркер, указывающий на то, что объявление устарело и было заменено новым
@SuppressWarningsУказывает на то, что одно или несколько предупреждающих сообщений, которые могут быть сгенерированы при компиляции, должны быть подавлены. Предупреждающие сообщения задаются именами, представленными в строковом виде

Ниже приведен пример, в котором аннотацией @Deprecated помечаются класс MyClass и метод getMsg(). При попытке скомпилировать программу будет выведено сообщение о том, что в исходном коде содержатся устаревшие и не рекомендованные к применению элементы.

Упражнение для самопроверки по материалу главы 12

Источник

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

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