Синтаксис Java - Java syntax

Фрагмент кода Java с ключевыми словами, выделенными жирным синим шрифтом.

В синтаксис из Ява относится к свод правил определение того, как пишется и интерпретируется программа Java.

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

Синтаксис Java постепенно расширялся в ходе многих основных JDK релизы, и теперь поддерживает такие возможности, как общее программирование и функциональные литералы (в Java они называются лямбда-выражениями). С 2017 года новая версия JDK выпускается два раза в год, причем каждый выпуск вносит в язык дополнительные улучшения.

Основы

Идентификатор

An идентификатор это имя элемента в код. Есть определенный стандарт соглашения об именах следовать при выборе имен для элементов. Идентификаторы в Java чувствительный к регистру.

Идентификатор может содержать:

  • Любой символ Юникода, представляющий собой букву (включая числовые буквы, например римские цифры ) или цифру.
  • Знак валюты (например, ¥).
  • Соединительный знак препинания (например, _ ).

Идентификатор не может:

  • Начните с цифры.
  • Быть равным зарезервированному ключевому слову, нулевому литералу или логическому литералу.

Ключевые слова

АбстрактныеПродолжитьзановыйвыключатель
утверждатьдефолтидти купаковкасинхронизированный
логическийделатьесличастныйэто
переменадвойнойорудиязащищенныйбросать
байтещеимпортобщественныйбросает
кейсперечислитьэкземплярвозвращатьсяпреходящий
ловитьрасширяетintкороткаяпытаться
charокончательныйинтерфейсстатическийвар
учебный класснаконец-тодлинныйstrictfpпустота
constплаватьродныесуперлетучий
пока

Литералы

Целые числа
двоичный (введено в Java SE 7)0b11110101 (0b за которым следует двоичное число)
восьмеричный0365 (0 за которым следует восьмеричное число)
шестнадцатеричный0xF5 (0x за которым следует шестнадцатеричное число)
десятичный245 (десятичное число)
Плавающая точка значения
плавать23,5F, .5f, 1.72E3F (десятичная дробь с необязательным индикатором степени, за которой следует F)
0x.5FP0F, 0x.5P-6f (0x за которой следует шестнадцатеричная дробь с обязательным индикатором степени и суффиксом F)
двойной23,5D, .5, 1.72E3D (десятичная дробь с необязательным индикатором экспоненты, за которой следует необязательный D)
0x.5FP0, 0x.5P-6D (0x за которой следует шестнадцатеричная дробь с обязательным индикатором степени и необязательным суффиксом D)
Символьные литералы
char'а', 'Z', ' u0231' (символ или escape-символ, заключенный в одинарные кавычки)
Логические литералы
логическийистинный, ложный
нулевой литерал
пустая ссылканоль
Строковые литералы
Строка"Привет, мир" (последовательность символов и escape-символов заключена в двойные кавычки)
Персонажи сбегают по строкам
Unicode персонаж u3876 ( u с последующим шестнадцатеричным кодом Unicode до U + FFFF)
Восьмеричный побег\352 (восьмеричное число, не превышающее 377, которому предшествует обратная косая черта)
Перевод строки п
Возврат кареткир
Подача формы f
Обратная косая черта\\
Одиночная цитата\'
Двойная кавычка\"
Вкладка т
Backspace b

Целочисленные литералы имеют int введите по умолчанию, если длинный тип указывается добавлением L или же л суффикс к буквальному, например 367L. Начиная с Java SE 7, можно включать символы подчеркивания между цифрами числа для повышения удобочитаемости; например, число 145608987 можно записать как 145_608_987.

Переменные

Переменные - идентификаторы, связанные со значениями. Они объявляются путем записи типа и имени переменной и, возможно, инициализируются в том же операторе путем присвоения значения.

int считать;      // Объявление неинициализированной переменной с именем 'count' типа 'int'считать = 35;     // Инициализируем переменнуюint считать = 35; // Объявление и инициализация переменной одновременно

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

int а, б;         // Объявление нескольких переменных одного типаint а = 2, б = 3; // Объявление и инициализация нескольких переменных одного типа

Начиная с Java 10 стало возможным автоматически определять типы переменных с помощью вар.

// поток будет иметь тип FileOutputStream, как выводится из его инициализаторавар транслировать = новый FileOutputStream("file.txt");// Эквивалентное объявление с явным типомFileOutputStream транслировать = новый FileOutputStream("file.txt");

Блоки кода

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

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

пустота сделай что-нибудь() {    int а;    {        int б;        а = 1;    }    а = 2;    б = 3; // Недопустимо, потому что переменная b объявлена ​​во внутренней области видимости ..}

Комментарии

В Java есть три вида комментариев: традиционные комментарии, комментарии в конце строки и комментарии к документации.

Традиционные комментарии, также известные как комментарии блоков, начинаются с /* и закончить */, они могут занимать несколько строк. Этот тип комментария был получен из C и C ++.

/ * Это многострочный комментарий.Он может занимать более одной строки. * /

Комментарии в конце строки начинаются с // и продлить до конца текущей строки. Этот тип комментария также присутствует в C ++ и в современном C.

// Это комментарий в конце строки

Комментарии к документации в исходных файлах обрабатываются Javadoc инструмент для создания документации. Этот тип комментария идентичен традиционным комментариям, за исключением того, что он начинается с /** и следует соглашениям, определенным инструментом Javadoc. Технически эти комментарии представляют собой особый вид традиционных комментариев, и они специально не определены в спецификации языка.

/** * Это комментарий к документации. *  * @ автор Джон Доу */

Универсальные типы

Классы в пакете java.lang неявно импортируются в каждую программу, если никакие явно импортированные типы не имеют одинаковых имен. К важным относятся:

java.lang.Object
Java верхний тип. Суперкласс всех классов, не объявляющих родительский класс. Все значения могут быть преобразованы в этот тип, хотя для примитивных значений это включает автобокс.
java.lang.String
Базовый строковый тип Java. Неизменный. Некоторые методы лечат каждого UTF-16 кодовая единица как "символ", но методы преобразования в int [] это эффективно UTF-32 также доступны.
java.lang.Throwable
супертип всего, что может быть брошенный или пойманный с Java бросать и ловить заявления.

Структура программы

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

главный метод

Каждое приложение Java должно иметь точку входа. Это верно как для приложений с графическим интерфейсом, так и для консольных приложений. Точка входа - это главный метод. Может быть более одного класса с главный метод, но основной класс всегда определяется извне (например, в файл манифеста ). Метод должен быть статический и ему передаются аргументы командной строки в виде массива строк. В отличие от C ++ или же C #, он никогда не возвращает значение и должен возвращать пустота.

общественный статический пустота главный(Строка[] аргументы) {}

Пакеты

Пакеты являются частью имени класса и используются для группировки и / или отличия именованных сущностей от других. Другая цель пакетов - управлять доступом к коду вместе с модификаторами доступа. Например, java.io.InputStream это полное имя класса для класса InputStream который находится в упаковке java.io.

Пакет объявляется в начале файла с упаковка декларация:

упаковка myapplication.mylibrary;общественный учебный класс Мой класс {}

Занятия с общественный модификатор необходимо разместить в одноименных файлах и Ява extension и поместите во вложенные папки, соответствующие имени пакета. Вышеупомянутый класс myapplication.mylibrary.MyClass будет следующий путь: myapplication / mylibrary / MyClass.java.

Декларация импорта

Тип импортной декларации

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

упаковка myPackage;импорт java.util.Random; // Объявление единого типаобщественный учебный класс ImportsTest {    общественный статический пустота главный(Строка[] аргументы) {        / * Следующая строка эквивалентна         * java.util.Random random = новый java.util.Random ();         * Было бы неправильно без импорта.         */        Случайный случайный = новый Случайный();    }}

В коде упоминаются декларации об импорте по запросу. «Импорт типа» импортирует все типы пакета. «Статический импорт» импортирует элементы пакета.

импорт java.util. *;  / * Эта форма импорта классов делает все классы    в пакете java.util, доступном по имени, может использоваться вместо    объявление import в предыдущем примере. * /импорт Ява.*; / * Этот оператор допустим, но ничего не делает, так как там    нет классов непосредственно в пакете java. Все они в пакетах    в пакете java. Это не импортирует все доступные классы. * /

Статическая импортная декларация

Этот тип объявления доступен с J2SE 5.0. Статический импорт объявления разрешают доступ к статическим членам, определенным в другом классе, интерфейсе, аннотации или перечислении; без указания имени класса:

импорт статических java.lang.System.out; // 'out' - это статическое поле в java.lang.Systemобщественный учебный класс Привет, мир {    общественный статический пустота главный(Строка[] аргументы) {        / * Следующая строка эквивалентна:   System.out.println («Привет, мир!»);           и было бы неправильно без декларации импорта. * /        из.println("Привет, мир!");    }}

Объявления импорта по запросу позволяют импортировать все поля типа:

импорт статических java.lang.System. *;    / * Эта форма объявления делает все       поля в классе java.lang.System доступны по имени и могут использоваться вместо       объявления импорта в предыдущем примере. * /

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

общественный перечислить ColorName {    КРАСНЫЙ, СИНИЙ, ЗЕЛЕНЫЙ};

Для получения констант перечисления можно использовать статические объявления импорта в другом классе:

импорт screen.ColorName;импорт статических screen.ColorName. *;общественный учебный класс Точки {    / * Следующая строка эквивалентна 'ColorName foo = ColorName.RED',       и это было бы неправильно без статического импорта. * /    ColorName фу = КРАСНЫЙ;    пустота сдвиг() {        / * Следующая строка эквивалентна:           if (foo == ColorName.RED) foo = ColorName.BLUE; * /        если (фу == КРАСНЫЙ) фу = СИНИЙ;    }}

Операторы

Операторы в Java аналогичны операторам в C ++. Однако нет Удалить оператор из-за вывоз мусора механизмы в Java, и нет операций с указатели поскольку Java их не поддерживает. Другое отличие состоит в том, что в Java есть беззнаковый оператор сдвига вправо (>>>), в то время как подпись оператора правого сдвига C зависит от типа. Операторы в Java не могут быть перегружен.

ПриоритетОператорОписаниеАссоциативность
1()Вызов методаСлева направо
[]Доступ к массиву
.Выбор членов класса
2++ --Постфиксное увеличение и уменьшение[1]
3++ --Увеличение и уменьшение префиксаСправа налево
+ -Унарный плюс и минус
! ~Логическое НЕ и побитовое НЕ
(тип) valПриведение типов
новыйСоздание экземпляра класса или массива
4* / %Умножение, деление и модуль (остаток)Слева направо
5+ -Сложение и вычитание
+Конкатенация строк
6<< >> >>>Побитовое сдвиг влево, сдвиг вправо со знаком и сдвиг вправо без знака
7< <=Реляционный «Меньше» и «меньше или равно»
> >=Отношения «больше чем» и «больше или равно»
экземплярСравнение типов
8== !=Отношения «равно» и «не равно»
9&Побитовое и логическое И
10^Побитовое и логическое исключающее ИЛИ (исключающее ИЛИ)
11|Побитовое и логическое ИЛИ (включающее или)
12&&Логическое условное И
13||Логическое условное ИЛИ
14c ? т : жТроичный условный (см. ?: )Справа налево
15=Простое задание
+= -=Назначение по сумме и разнице
*= /= %=Присвоение по продукту, частному и остатку
<<= >>= >>>=Присваивание с помощью побитового сдвига влево, сдвига вправо со знаком и сдвига вправо без знака
&= ^= |=Присваивание с помощью побитовых операций AND, XOR и OR

Структуры управления

Условные утверждения

если утверждение

если заявления в Java аналогичны таковым в C и используют тот же синтаксис:

если (я == 3) сделай что-нибудь();

если заявление может включать необязательные еще блок, и в этом случае он становится оператором if-then-else:

если (я == 2) {    сделай что-нибудь();} еще {    doSomethingElse();}

Как и в C, конструкция else-if не включает каких-либо специальных ключевых слов, она формируется как последовательность отдельных операторов if-then-else:

если (я == 3) {    сделай что-нибудь();} еще если (я == 2) {    doSomethingElse();} еще {    doSomethingDifferent();}

Также обратите внимание, что ?: оператор может использоваться вместо простого оператора if, например

int а = 1;int б = 2;int minVal = (а < б) ? а : б;

выключатель утверждение

Операторы переключения в Java можно использовать байт, короткая, char, и int (примечание: не длинный) примитивные типы данных или соответствующие им типы-оболочки. Начиная с J2SE 5.0, можно использовать типы перечисления. Начиная с Java SE 7, можно использовать строки. Другие ссылочные типы не могут использоваться в выключатель заявления.

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

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

выключатель (ch) {    кейс 'А':        сделай что-нибудь(); // Срабатывает, если ch == 'A'        перемена;    кейс 'B':    кейс 'C':        doSomethingElse(); // Срабатывает, если ch == 'B' или ch == 'C'        перемена;    дефолт:        doSomethingDifferent(); // Срабатывает в любом другом случае        перемена;}
выключатель выражения

Начиная с Java 14 стало возможным использовать выражения переключения, в которых используется новый синтаксис стрелок:

вар результат = выключатель (ch) {    кейс 'А' -> Результат.ЗДОРОВО;    кейс 'B', 'C' -> Результат.ОТЛИЧНО;    дефолт -> бросать новый ThisIsNoGoodException();};

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

вар результат = выключатель (ch) {    кейс 'А':        урожай Результат.ЗДОРОВО;    кейс 'B':    кейс 'C':        урожай Результат.ОТЛИЧНО;    дефолт:        бросать новый ThisIsNoGoodException();};

Операторы итерации

Операторы итерации - это операторы, которые повторно выполняются, когда данное условие оценивается как истинное. С J2SE 5.0, В Java есть четыре формы таких операторов.

пока петля

в пока цикл, проверка выполняется перед каждой итерацией.

пока (я < 10) {    сделай что-нибудь();}

делать пока петля

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

// doSomething () вызывается хотя бы один разделать {    сделай что-нибудь();} пока (я < 10);

за петля

за циклы в Java включают инициализатор, условие и выражение счетчика. Можно включить несколько выражений одного типа, используя запятую в качестве разделителя (кроме условия). Однако, в отличие от C, запятая - это просто разделитель, а не оператор.

за (int я = 0; я < 10; я++) {    сделай что-нибудь();} // Более сложный цикл с двумя переменнымиза (int я = 0, j = 9; я < 10; я++, j -= 3) {    сделай что-нибудь();}

Как и в C, все три выражения необязательны. Следующий цикл бесконечен:

за (;;) {    сделай что-нибудь();}

Повышенная за петля

Повышенная за петли были доступны с J2SE 5.0. Этот тип цикла использует встроенные итераторы массивов и коллекций для возврата каждого элемента в данной коллекции. Каждый элемент возвращается и доступен в контексте блока кода. Когда блок выполняется, возвращается следующий элемент, пока не кончатся элементы. В отличие от C #, этот вид цикла не включает специального ключевого слова, а вместо этого использует другой стиль записи.

за (int я : intArray) {    сделай что-нибудь(я);}

Заявления о прыжках

Этикетки

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

Начните:someMethod();

перемена утверждение

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

за (int я = 0; я < 10; я++) {    пока (истинный) {        перемена;    }    // сломаемся до этого момента}

Вырваться из внешнего цикла можно с помощью меток:

внешний:за (int я = 0; я < 10; я++) {    пока (истинный) {        перемена внешний;    }}// Сломаемся до этого момента

Продолжить утверждение

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

int ch;пока (ch == getChar()) {    если (ch == ' ') {        Продолжить; // Пропускает оставшуюся часть цикла while    }    // Остальная часть цикла while не будет достигнута, если ch == ''    сделай что-нибудь();}

Ярлыки могут быть указаны в Продолжить заявления и перемена заявления:

внешний:за (Строка ул : stringsArr) {    char[] strChars = ул.toCharArray();    за (char ch : strChars) {        если (ch == ' ') {            / * Продолжаем внешний цикл и следующий            строка извлекается из stringsArr * /            Продолжить внешний;        }        сделай что-нибудь(ch);    }}

возвращаться утверждение

В возвращаться Оператор используется для завершения выполнения метода и возврата значения. Значение, возвращаемое методом, записывается после возвращаться ключевое слово. Если метод возвращает что-нибудь, кроме пустота, он должен использовать возвращаться оператор для возврата некоторого значения.

пустота сделай что-нибудь(логический поток закрыт) {    // Если streamClosed истинно, выполнение останавливается    если (поток закрыт) {        возвращаться;    }    readFromStream();}int CalculSum(int а, int б) {    int результат = а + б;    возвращаться результат;}

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

пустота сделай что-нибудь(логический поток закрыт) {    пытаться {        если (поток закрыт) {            возвращаться;        }        readFromStream();    } наконец-то {        / * Будет вызываться последним, даже если         readFromStream () не был вызван * /        freeResources();    }}

Операторы обработки исключений

попробовать-поймать-наконец заявления

Исключения обрабатываются в пытаться ... ловить блоки.

пытаться {    // Заявления, которые могут вызывать исключения    methodThrowingExceptions();} ловить (Исключение бывший) {    // Исключение поймано и обработано здесь    reportException(бывший);} наконец-то {    // Операторы всегда выполняются после блоков try / catch    freeResources();}

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

В Java SE 7, помимо предложений uni-catch, также были введены предложения с несколькими перехватами. Этот тип предложений catch позволяет Java обрабатывать различные типы исключений в одном блоке при условии, что они не являются подклассами друг друга.

пытаться {    methodThrowingExceptions();} ловить (IOException | IllegalArgumentException бывший) {    // Здесь будут пойманы и обработаны исключения IOException и IllegalArgumentException    reportException(бывший);}

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

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

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

пытаться-with-resources операторы

пытаться-with-resources операторы - это особый тип попробовать-поймать-наконец операторы, представленные как реализация шаблон утилизации в Java SE 7. В пытаться-with-resources заявление пытаться за ключевым словом следует инициализация одного или нескольких ресурсов, которые автоматически освобождаются, когда пытаться выполнение блока завершено. Ресурсы должны реализовывать java.lang.AutoCloseable. пытатьсяОператоры -with-resources не обязаны иметь ловить или же наконец-то блок в отличие от обычного попробовать-поймать-наконец заявления.

пытаться (FileOutputStream фос = новый FileOutputStream("имя файла");    XMLEncoder xEnc = новый XMLEncoder(фос)) {    xEnc.writeObject(объект);} ловить (IOException бывший) {    Регистратор.getLogger(Сериализатор.учебный класс.getName()).бревно(Уровень.СУРОВЫЙ, ноль, бывший);}

Начиная с Java 9 можно использовать уже объявленные переменные:

FileOutputStream фос = новый FileOutputStream("имя файла");XMLEncoder xEnc = новый XMLEncoder(фос);пытаться (фос; xEnc) {    xEnc.writeObject(объект);} ловить (IOException бывший) {    Регистратор.getLogger(Сериализатор.учебный класс.getName()).бревно(Уровень.СУРОВЫЙ, ноль, бывший);}

бросать утверждение

В бросать Оператор используется для создания исключения и завершения выполнения блока или метода. Созданный экземпляр исключения записывается после бросать утверждение.

пустота methodThrowingExceptions(Объект объект) {    если (объект == ноль) {        // Выдает исключение типа NullPointerException        бросать новый Исключение нулевого указателя();    }    // Не будет вызываться, если объект нулевой    doSomethingWithObject(объект);}

Контроль параллелизма потоков

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

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

/ * Получает блокировку для someObject. Это должно быть изссылочный тип и должен быть ненулевым * /синхронизированный (someObject) {    // Синхронизированные операторы}

утверждать утверждение

утверждать заявления были доступны с J2SE 1.4. Эти типы заявлений используются, чтобы сделать утверждения в исходном коде, который можно включать и выключать во время выполнения для определенных классов или пакетов. Чтобы объявить утверждение утверждать используется ключевое слово, за которым следует условное выражение. Если он оценивается как ложный когда инструкция выполняется, выдается исключение. Этот оператор может включать двоеточие, за которым следует другое выражение, которое будет действовать как подробное сообщение об исключении.

// Если n равно 0, выдается AssertionErrorутверждать п != 0;/ * Если n равно 0, будет сгенерирована ошибка AssertionErrorс сообщением после двоеточия * /утверждать п != 0 : "n было равно нулю";

Примитивные типы

Примитивные типы в Java включают целочисленные типы, числа с плавающей запятой, UTF-16 единицы кода и логический тип. В Java нет беззнаковых типов, кроме char type, который используется для представления кодовых единиц UTF-16. Отсутствие беззнаковых типов компенсируется введением беззнаковой операции сдвига вправо (>>>), которого нет в C ++. Тем не менее, были высказаны критические замечания по поводу отсутствия совместимости с C и C ++ по этой причине.[2]

Примитивные типы
Тип ИмяКласс-оболочкаЦенитьКлассифицироватьРазмерЗначение по умолчанию
байтjava.lang.Byteцелое числоОт −128 до +1278-битный (1-байтный)0
короткаяjava.lang.Shortцелое числоОт −32,768 до +32,76716 бит (2 байта)0
intjava.lang.Integerцелое числоОт −2 147 483 648 до +2 147 483 64732-битный (4-байтовый)0
длинныйjava.lang.Longцелое число−9 223 372 036 854 775 808 через
+9,223,372,036,854,775,807
64-битный (8-байтный)0
плаватьjava.lang.Floatчисло с плавающей запятойОт ± 1,401298E-45 до ± 3,402823E + 3832-битный (4-байтовый)0,0f[3]
двойнойjava.lang.Doubleчисло с плавающей запятой± 4.94065645841246E − 324 через
± 1,79769313486232E + 308
64-битный (8-байтный)0.0
логическийjava.lang.BooleanБулевоистинный или же ложный1 бит (1 бит)ложный
charjava.lang.CharacterUTF-16 кодовый блок (BMP персонаж
или часть суррогатной пары)
' u0000' через ' uFFFF'16 бит (2 байта)' u0000'

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

Бокс и распаковка

Эта языковая функция была представлена ​​в J2SE 5.0. Заниматься боксом - это операция преобразования значения примитивного типа в значение соответствующего ссылочного типа, которое служит оболочкой для этого конкретного примитивного типа. Распаковка - это обратная операция преобразования значения ссылочного типа (ранее помещенного в штучную упаковку) в значение соответствующего примитивного типа. Ни одна из операций не требует явного преобразования.

Пример:

int фу = 42; // Примитивный типЦелое число бар = фу; / * foo помещается в рамку, bar имеет тип Integer,                      который служит оболочкой для int * /int foo2 = бар; // Распаковка обратно в примитивный тип

Типы ссылок

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

Ссылочная переменная ноль когда он не ссылается ни на один объект.

Массивы

Массивы в Java создаются во время выполнения, как и экземпляры классов. Длина массива определяется при создании и не может быть изменена.

int[] числа = новый int[5];числа[0] = 2;числа[1] = 5;int Икс = числа[0];

Инициализаторы

// Длинный синтаксисint[] числа = новый int[] {20, 1, 42, 15, 34};// Краткий синтаксисint[] числа2 = {20, 1, 42, 15, 34};

Многомерные массивы

В Java многомерные массивы представлены как массивы массивов. Технически они представлены массивами ссылок на другие массивы.

int[][] числа = новый int[3][3];числа[1][2] = 2;int[][] числа2 = {{2, 3, 2}, {1, 2, 6}, {2, 4, 5}};

Из-за природы многомерных массивов подмассивы могут различаться по длине, поэтому многомерные массивы не обязательно должны быть прямоугольными, в отличие от C:

int[][] числа = новый int[2][]; // Инициализация только первого измерениячисла[0] = новый int[3];числа[1] = новый int[2];

Классы

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

Декларация

Класс высшего уровня
учебный класс Фу {    // Члены класса}
Внутренний класс
учебный класс Фу { // Класс верхнего уровня    учебный класс Бар { // Внутренний класс    }}
Вложенный класс
учебный класс Фу { // Класс верхнего уровня    статический учебный класс Бар { // Вложенный класс    }}
Местный класс
учебный класс Фу {    пустота бар() {        учебный класс Foobar {// Локальный класс внутри метода        }    }}
Анонимный класс
учебный класс Фу {    пустота бар() {        новый Объект() {// Создание нового анонимного класса, расширяющего Object        };    }}

Создание

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

Фу фу = новый Фу();

Доступ к участникам

Доступ к членам как экземпляров, так и статических классов осуществляется с помощью . (точка) оператор.

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

Строка фу = "Привет";Строка бар = фу.toUpperCase();

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

общественный учебный класс Фу {    общественный статический пустота сделай что-нибудь() {    }}// Вызов статического методаФу.сделай что-нибудь();

Модификаторы

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

  • Абстрактные - Указывает, что класс служит только базовым классом и не может быть создан.
  • статический - Используется только для классов-членов, указывает, что класс-член не принадлежит определенному экземпляру содержащего класса.
  • окончательный - Классы, отмеченные как окончательный не может быть расширен и не может иметь подклассов.
  • strictfp - Указывает, что все операции с плавающей запятой должны выполняться в соответствии с IEEE 754 и запрещает использование повышенной точности для хранения промежуточных результатов.
Модификаторы доступа

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

общественный учебный класс Фу {    int идти() {        возвращаться 0;    }    частный учебный класс Бар {    }}

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

МодификаторТот же класс или вложенный классДругой класс внутри того же пакетаРасширенный класс внутри другого пакетаНе расширен внутри другого пакета
частныйданетнетнет
по умолчанию (частный пакет)даданетнет
защищенныйдададанет
общественныйдададада
Это изображение описывает область действия члена класса внутри классов и пакетов.

Конструкторы и инициализаторы

А конструктор - это специальный метод, вызываемый при инициализации объекта. Его цель - инициализировать члены объекта. Основные различия между конструкторами и обычными методами заключаются в том, что конструкторы вызываются только при создании экземпляра класса и никогда ничего не возвращают. Конструкторы объявлены как общие методы, но названы в честь класса, и тип возвращаемого значения не указан:

учебный класс Фу {    Строка ул;    Фу() { // Конструктор без аргументов        // Инициализация    }    Фу(Строка ул) { // Конструктор с одним аргументом        это.ул = ул;    }}

Инициализаторы - это блоки кода, которые выполняются при создании класса или экземпляра класса. Есть два типа инициализаторов: статические инициализаторы и инициализаторы экземпляров.

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

учебный класс Фу {    статический {        // Инициализация    }}

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

учебный класс Фу {    {        // Инициализация    }}

Поскольку в Java есть механизм сборки мусора, нет деструкторы. Однако у каждого объекта есть финализировать () метод, вызываемый перед сборкой мусора, который может быть отвергнутый осуществить доработку.

Методы

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

учебный класс Фу {    int бар(int а, int б) {        возвращаться (а*2) + б;    }    / * Перегруженный метод с тем же именем, но другим набором аргументов * /    int бар(int а) {        возвращаться а*2;    }}

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

Фу фу = новый Фу();int результат = фу.бар(7, 2); // Нестатический метод вызывается для fooint конечный результат = Математика.пресс(результат); // Вызов статического метода

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

пустота openStream() бросает IOException, myException { // Указывает, что может быть сгенерировано исключение IOException}
Модификаторы
  • Абстрактные - Абстрактные методы может присутствовать только в абстрактные классы такие методы не имеют тела и должны быть переопределены в подклассе, если он сам не является абстрактным.
  • статический - Делает метод статическим и доступным без создания экземпляра класса. Однако статические методы не могут получить доступ к нестатическим членам того же класса.
  • окончательный - Объявляет, что метод не может быть переопределен в подклассе.
  • родные - Указывает, что этот метод реализован через JNI в платформо-зависимом коде. Фактическая реализация происходит вне кода Java, и такие методы не имеют тела.
  • strictfp - Декларирует строгое соответствие IEEE 754 при выполнении операций с плавающей запятой.
  • синхронизированный - Объявляет, что поток, выполняющий этот метод, должен получить монитор. За синхронизированный методы, монитор является экземпляром класса или java.lang.Class если метод статический.
  • Модификаторы доступа - идентичны тем, которые используются с классами.
Вараргс

Эта языковая функция была представлена ​​в J2SE 5.0. Последний аргумент метода может быть объявлен как параметр переменной арности, и в этом случае метод становится методом переменной арности (в отличие от методов фиксированной арности) или просто varargs метод. Это позволяет передавать в метод переменное количество значений объявленного типа в качестве параметров, включая отсутствие параметров. Эти значения будут доступны внутри метода в виде массива.

пустота printReport(Строка заголовок, int... числа) { // числа представляют varargs    Система.из.println(заголовок);    за (int число : числа) {        Система.из.println(число);    }}// Вызов метода varargsprintReport(«Данные отчета», 74, 83, 25, 96);

Поля

Поля или переменные класса могут быть объявлены внутри тела класса для хранения данных.

учебный класс Фу {    двойной бар;}

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

учебный класс Фу {    двойной бар = 2.3;}
Модификаторы
  • статический - Делает поле статическим членом.
  • окончательный - Позволяет инициализировать поле только один раз в конструкторе или внутри блока инициализации или во время его объявления, в зависимости от того, что произойдет раньше.
  • преходящий - Указывает, что это поле не будет сохранено во время сериализация.
  • летучий - Если поле объявлено летучий, гарантируется, что все потоки видят согласованное значение переменной.

Наследование

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

учебный класс Фу {}учебный класс Foobar расширяет Фу {}

Если класс не указывает свой суперкласс, он неявно наследуется от java.lang.Object учебный класс. Таким образом, все классы в Java являются подклассами Объект учебный класс.

Если у суперкласса нет конструктора без параметров, подкласс должен указать в своих конструкторах, какой конструктор суперкласса использовать. Например:

учебный класс Фу {    общественный Фу(int п) {        // Делаем что-нибудь с n    }}учебный класс Foobar расширяет Фу {    частный int номер;    // У суперкласса нет конструктора без параметров    // поэтому мы должны указать, какой конструктор нашего суперкласса использовать и как    общественный Foobar(int номер) {        супер(номер);        это.номер = номер;    }}
Методы переопределения

В отличие от C ++, все не-окончательный методы в Java виртуальный и могут быть переопределены наследующими классами.

учебный класс Операция {    общественный int сделай что-нибудь() {        возвращаться 0;    }}учебный класс NewOperation расширяет Операция {    @Override    общественный int сделай что-нибудь() {        возвращаться 1;    }}
Абстрактные классы

An Абстрактный класс - это класс, который является неполным или считается неполным. Нормальные классы могут иметь абстрактные методы, то есть методы, которые объявлены, но еще не реализованы, только если они являются абстрактными классами. Класс C имеет абстрактные методы, если любое из следующих правда:

  • C явно содержит объявление абстрактного метода.
  • Любой из суперклассов C имеет абстрактный метод, и C не объявляет и не наследует метод, который его реализует.
  • Прямой суперинтерфейс C объявляет или наследует метод (который поэтому обязательно является абстрактным), а C не объявляет и не наследует метод, который его реализует.
  • Подкласс абстрактного класса, который сам не является абстрактным, может быть создан, что приведет к выполнению конструктора абстрактного класса и, следовательно, выполнению инициализаторов полей для переменных экземпляра этого класса.
упаковка org.dwwwp.test;/** * @author jcrypto */общественный учебный класс AbstractClass {    частный статический окончательный Строка Привет;    статический {        Система.из.println(AbstractClass.учебный класс.getName() + ": время выполнения статического блока");        Привет = "Привет из " + AbstractClass.учебный класс.getName();    }    {        Система.из.println(AbstractClass.учебный класс.getName() + ": среда выполнения блока экземпляра");    }    общественный AbstractClass() {        Система.из.println(AbstractClass.учебный класс.getName() + ": среда выполнения конструктора");    }    общественный статический пустота Привет() {        Система.из.println(Привет);    }}
упаковка org.dwwwp.test;/** * @author jcrypto */общественный учебный класс CustomClass расширяет AbstractClass {    статический {        Система.из.println(CustomClass.учебный класс.getName() + ": время выполнения статического блока");    }    {        Система.из.println(CustomClass.учебный класс.getName() + ": среда выполнения блока экземпляра");    }    общественный CustomClass() {        Система.из.println(CustomClass.учебный класс.getName() + ": среда выполнения конструктора");    }    общественный статический пустота главный(Строка[] аргументы) {        CustomClass NC = новый CustomClass();        Привет();        //AbstractClass.hello();// также действителен    }}

Выход:

org.dwwwp.test.AbstractClass: статический блок runtimeorg.dwwwp.test.CustomClass: статический блок runtimeorg.dwwwp.test.AbstractClass: исполняемый блок экземпляра .dwwwp.test.CustomClass: время выполнения конструктора hello из org.dwwwp.test.AbstractClass

Перечисления

Эта языковая функция была представлена ​​в J2SE 5.0. Технически перечисления - это своего рода класс, содержащий в своем теле константы перечисления. Каждая константа перечисления определяет экземпляр типа перечисления. Классы перечисления не могут быть созданы нигде, кроме самого класса перечисления.

перечислить Время года {    ЗИМА, ВЕСНА, ЛЕТОМ, ОСЕНЬ}

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

общественный перечислить Время года {    ЗИМА("Холодный"), ВЕСНА("Грелка"), ЛЕТОМ("Горячей"), ОСЕНЬ("Кулер");    Время года(Строка описание) {        это.описание = описание;    }    частный окончательный Строка описание;    общественный Строка getDescription() {        возвращаться описание;    }}

Перечисления могут иметь тела классов, и в этом случае они рассматриваются как анонимные классы, расширяющие класс перечисления:

общественный перечислить Время года {    ЗИМА {        Строка getDescription() {возвращаться "холодный";}    },    ВЕСНА {        Строка getDescription() {возвращаться "грелка";}    },    ЛЕТОМ {        Строка getDescription() {возвращаться "горячей";}    },    ОСЕНЬ {        Строка getDescription() {возвращаться "кулер";}    };}

Интерфейсы

Интерфейсы - это типы, которые не содержат полей и обычно определяют ряд методов без фактической реализации. Они полезны для определения контракта с любым количеством различных реализаций. Каждый интерфейс неявно абстрактен. Методы интерфейса могут иметь подмножество модификаторов доступа в зависимости от языковой версии, strictfp, что имеет тот же эффект, что и для классов, а также статический начиная с Java SE 8.

интерфейс ActionListener {    int ACTION_ADD = 0;    int ACTION_REMOVE = 1;     пустота actionSelected(int действие);}

Реализация интерфейса

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

интерфейс RequestListener {    int запрос принят();}учебный класс ActionHandler орудия ActionListener, RequestListener {    общественный пустота actionSelected(int действие) {    }    общественный int запрос принят() {    }}// Вызов метода, определяемого интерфейсомRequestListener слушатель = новый ActionHandler(); / * ActionHandler может быть                                   представлен как RequestListener ... * /слушатель.запрос принят(); /*...и, как известно, реализует                            requestReceived () метод * /

Функциональные интерфейсы и лямбда-выражения

Эти функции были представлены с выпуском Java SE 8. Интерфейс автоматически становится функциональным интерфейсом, если он определяет только один метод. В этом случае реализация может быть представлена ​​как лямбда-выражение вместо того, чтобы реализовывать ее в новом классе, что значительно упрощает написание кода в функциональный стиль. Функциональные интерфейсы при желании могут быть аннотированы @FunctionalInterface аннотация, которая сообщит компилятору проверить, действительно ли интерфейс соответствует определению функционального интерфейса.

// Функциональный интерфейс@FunctionalInterfaceинтерфейс Расчет {    int вычислить(int someNumber, int someOtherNumber);}// Метод, который принимает этот интерфейс как параметрint runCalculation(Расчет расчет) {    возвращаться расчет.вычислить(1, 2);}// Использование лямбда для вызова методаrunCalculation((номер, otherNumber) -> номер + otherNumber);// Эквивалентный код, который вместо этого использует анонимный классrunCalculation(новый Расчет() {    @Override    общественный int вычислить(int someNumber, int someOtherNumber) {        возвращаться someNumber + someOtherNumber;    }})

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

// Тот же вызов, что и выше, но с полностью указанными типами и блоком телаrunCalculation((int номер, int otherNumber) -> {    возвращаться номер + otherNumber;});// Функциональный интерфейс с методом, имеющим только один параметринтерфейс StringExtender {    Строка extendString(Строка Вход);}// Инициализация переменной этого типа с помощью лямбдаStringExtender расширитель = Вход -> Вход + " Расширенный";

Ссылки на методы

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

Тип ссылкиПримерЭквивалентная лямбда
СтатическийЦелое число :: сумма(число, другое число) -> число + другое число
Граница"LongString" :: подстрокаindex -> "LongString" .substring (индекс)
НесвязанныйСтрока :: isEmptyстрока -> строка.isEmpty ()
Конструктор классаArrayList :: новыйемкость -> новый список массивов (емкость)
Конструктор массиваString [] :: newразмер -> новая строка [размер]

Код выше, который вызывает runCalculation можно заменить следующим, используя ссылки на методы:

runCalculation(Целое число::сумма);

Наследование

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

/ * Класс, реализующий этот интерфейс, должен реализовывать методы обоихActionListener и RequestListener * /интерфейс EventListener расширяет ActionListener, RequestListener {    }

Методы по умолчанию

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

интерфейс StringManipulator {    Строка extendString(Строка Вход);        // Метод, который необязательно реализовывать    дефолт Строка shortString(Строка Вход) {        возвращаться Вход.подстрока(1);    }}// Это допустимый класс, несмотря на то, что не реализованы все методыучебный класс PartialStringManipulator орудия StringManipulator {    @Override    общественный Строка extendString(Строка Вход) {        возвращаться Вход + " Расширенный";    }}

Статические методы

Статические методы - это еще одна языковая функция, представленная в Java SE 8. Они ведут себя точно так же, как и классы.

интерфейс StringUtils {    статический Строка shortByOneSymbol(Строка Вход) {        возвращаться Вход.подстрока(1);    }}StringUtils.shortByOneSymbol("Тест");

Частные методы

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

интерфейс Регистратор {    дефолт пустота logError() {        бревно(Уровень.ОШИБКА);    }    дефолт пустота logInfo() {        бревно(Уровень.ИНФОРМАЦИЯ);    }    частный пустота бревно(Уровень уровень) {        SystemLogger.бревно(уровень.я бы);    }}

Аннотации

Аннотации в Java - это способ встраивать метаданные в код. Эта языковая функция была представлена ​​в J2SE 5.0.

Типы аннотаций

В Java есть набор предопределенных типов аннотаций, но можно определять новые. Объявление типа аннотации - это особый тип объявления интерфейса. Они объявлены так же, как интерфейсы, за исключением интерфейс ключевому слову предшествует @ знак. Все аннотации неявно расширены из java.lang.annotation.Annotation и не может быть продолжен ни из чего.

@интерфейс BlockingOperations {}

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

@интерфейс BlockingOperations {    логический fileSystemOperations();    логический networkOperations() дефолт ложный;}
Использование аннотаций

Аннотации могут использоваться в любом виде объявления, будь то пакет, класс (включая перечисления), интерфейс (включая аннотации), поле, метод, параметр, конструктор или локальную переменную. Также их можно использовать с константами перечисления. Аннотации объявляются с помощью @ знак перед именем типа аннотации, после которого в скобках записываются пары элемент-значение. Всем элементам без значения по умолчанию должно быть присвоено значение.

@BlockingOperations(/*обязательный*/ fileSystemOperations,/*необязательный*/ networkOperations = истинный)пустота openOutputStream() { // Аннотированный метод}

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

@Unused // Сокращение для @Unused ()пустота путешествие на Юпитер() {}

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

/ * Эквивалент @BlockingOperations (fileSystemOperations = true).networkOperations имеет значение по умолчанию ине требует присвоения значения * /@BlockingOperations(истинный)пустота openOutputStream() {}

Дженерики

Дженерики, или параметризованные типы, или параметрический полиморфизм это одна из основных функций, представленных в J2SE 5.0. До того, как были введены дженерики, требовалось явно объявить все типы. С помощью дженериков стало возможным одинаково работать с разными типами без объявления точных типов. Основная цель дженериков - обеспечение безопасности типов и обнаружение ошибок времени выполнения во время компиляции. В отличие от C #, информация об используемых параметрах недоступна во время выполнения из-за стирание типа.[4]

Общие классы

Классы можно параметризовать, добавив переменную типа внутри угловых скобок (< и >) после имени класса. Это делает возможным использование этой переменной типа в членах класса вместо фактических типов. Может быть несколько переменных типа, и в этом случае они объявляются в списке, разделенном запятыми.

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

/ * Этот класс имеет два типа переменных, T и V. T должен быть подтип ArrayList и реализовать интерфейс Formattable * /общественный учебный класс Картограф<Т расширяет ArrayList & Форматируемый, V> {    общественный пустота Добавить(Т множество, V предмет) {        // у массива есть метод add, потому что это подкласс ArrayList        множество.Добавить(предмет);    }}

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

/ * Mapper создается с CustomList как T и Integer как V.CustomList должен быть подклассом ArrayList и реализовывать Formattable * /Картограф<CustomList, Целое число> картограф = новый Картограф<CustomList, Целое число>();

Начиная с Java SE 7, можно использовать ромб (<>) вместо аргументов типа, и в этом случае будет выводиться последнее. Следующий код в Java SE 7 эквивалентен коду в предыдущем примере:

Картограф<CustomList, Целое число> картограф = новый Картограф<>();

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

/ * Любой экземпляр Mapper с CustomList в качестве первого параметраможно использовать независимо от второго. * /Картограф<CustomList, ?> картограф;картограф = новый Картограф<CustomList, Булево>();картограф = новый Картограф<CustomList, Целое число>();/ * Не принимает типы, которые используют что-либо, кромеподкласс Number в качестве второго параметра * /пустота addMapper(Картограф<?, ? расширяет Число> картограф) {}

Универсальные методы и конструкторы

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

учебный класс Картограф {    // Сам класс не является универсальным, конструктор    <Т, V> Картограф(Т множество, V предмет) {    }}/ * Этот метод принимает только массивы того же типа, что итип искомого элемента или его подтип * /статический <Т, V расширяет Т> логический содержит(Т предмет, V[] обр) {    за (Т currentItem : обр) {        если (предмет.равно(currentItem)) {            возвращаться истинный;        }    }    возвращаться ложный;}

Общие интерфейсы

Интерфейсы можно параметризовать так же, как классы.

интерфейс Расширяемый<Т расширяет Число> {    пустота добавить элемент(Т предмет);}// Этот класс параметризованучебный класс Множество<Т расширяет Число> орудия Расширяемый<Т> {    пустота добавить элемент(Т предмет) {    }}// А это не так, вместо этого используется явный типучебный класс IntegerArray орудия Расширяемый<Целое число> {    пустота добавить элемент(Целое число предмет) {    }}

Смотрите также

Рекомендации

  1. ^ «Операторы (Руководства по Java ™> Изучение языка Java> Основы языка)». docs.oracle.com. Oracle и / или ее дочерние компании. Получено 2015-06-16.
  2. ^ Оуэнс, Шон. «Java и unsigned int, unsigned short, unsigned byte, unsigned long и т. Д. (Точнее, их отсутствие)».
  3. ^ «Примитивные типы данных».
  4. ^ Дженерики во время выполнения (Руководство по программированию на C #)

внешняя ссылка