Spec-Zone.ru › Java Language Specification 11

Глава 3. Лексическая структура

Содержание

3.1. Unicode
3.2. Лексические преобразования
3.3. Экранирование Unicode
3.4. Разделители строк
3.5. Элементы ввода и токены
3.6. Пробелы
3.7. Комментарии
3.8. Идентификаторы
3.9. Ключевые слова
3.10. Литералы
3.10.1. Целочисленные литералы
3.10.2. Литералы с плавающей точкой
3.10.3. Булевы литералы
3.10.4. Символьные литералы
3.10.5. Строковые литералы
3.10.6. Последовательности экранирования для символьных и строковых литералов
3.10.7. Нулевой литерал
3.11. Разделители
3.12. Операторы

В этой главе описывается лексическая структура языка программирования Java.

Программы написаны на Unicode (§3.1), но для включения любого символа Unicode с использованием только символов ASCII предоставляются лексические преобразования (§3.2), например, с помощью экранирования Unicode (§3.3). Определены разделители строк (§3.4), чтобы поддерживать различные соглашения существующих систем, сохраняя при этом последовательность номеров строк.

Символы Unicode, полученные в результате лексических преобразований, сводятся к последовательности элементов ввода (§3.5), которые представляют пробелы (§3.6), комментарии (§3.7) и токены. Токены — это идентификаторы (§3.8), ключевые слова (§3.9), литералы (§3.10), разделители (§3.11) и операторы (§3.12) синтаксической грамматики.

3.1. Unicode

Программы пишутся с использованием набора символов Unicode. Сведения об этом наборе символов и связанных с ним кодировках можно найти в http://www.unicode.org/.

Платформа Java SE отслеживает стандарт Unicode по мере его развития. Точная версия Unicode, используемая конкретным выпуском, указана в документации класса Character.

Версии языка программирования Java до JDK 1.1 использовали Unicode 1.1.5. Обновления до более новых версий стандарта Unicode произошли в JDK 1.1 (до Unicode 2.0), JDK 1.1.7 (до Unicode 2.1), Java SE 1.4 (до Unicode 3.0), Java SE 5.0 (до Unicode 4.0), Java SE 7 (до Unicode 6.0), Java SE 8 (до Unicode 6.2), Java SE 9 (до Unicode 8.0) и Java SE 11 (до Unicode 10.0).

Изначально стандарт Unicode был разработан как кодировка символов с фиксированной шириной 16 бит. Позднее он был изменён, чтобы позволить использовать символы, представление которых требует более 16 бит. Диапазон допустимых кодовых точек теперь U+0000 до U+10FFFF, используя шестнадцатеричное обозначение U+n. Символы, кодовые точки которых больше U+FFFF, называются дополнительными символами. Для представления всего диапазона символов с использованием только 16-битовых единиц стандарт Unicode определяет кодировку UTF-16. В этой кодировке дополнительные символы представлены парами 16-битовых кодовых единиц, первая из диапазона высоких суррогатов (U+D800 до U+DBFF), вторая — из диапазона низких суррогатов (U+DC00 до U+DFFF). Для символов в диапазоне U+0000 до U+FFFF значения кодовых точек и кодовых единиц UTF-16 совпадают.

Язык программирования Java представляет текст в последовательностях 16-битовых кодовых единиц, используя кодировку UTF-16.

Некоторые API платформы Java SE, в основном в классе Character, используют 32-битовые целые числа для представления кодовых точек как отдельных сущностей. Платформа Java SE предоставляет методы для преобразования между 16-битными и 32-битными представлениями.

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

За исключением комментариев (§3.7), идентификаторов и содержимого символьных и строковых литералов (§3.10.4, §3.10.5), все элементы ввода (§3.5) в программе формируются только из символов ASCII (или экранирования Unicode (§3.3), которые приводят к символам ASCII).

ASCII (ANSI X3.4) — это американский стандартный код для обмена информацией. Первые 128 символов кодировки Unicode UTF-16 — это символы ASCII.

3.2. Лексические преобразования

Поток исходных символов Unicode преобразуется в последовательность токенов, используя следующие три шага лексического преобразования, которые применяются поочерёдно:

  1. Преобразование экранирования Unicode (§3.3) в исходном потоке символов Unicode в соответствующий символ Unicode. Экранирование Unicode в формате \uxxxx, где xxxx — шестнадцатеричное значение, представляет кодовую единицу UTF-16, чья кодировка равна xxxx. Этот шаг преобразования позволяет выразить любую программу, используя только символы ASCII.

  2. Преобразование потока Unicode, полученного на шаге 1, в поток входных символов и разделителей строк (§3.4).

  3. Преобразование потока входных символов и разделителей строк, полученного на шаге 2, в последовательность элементов ввода (§3.5), которые после удаления пробелов (§3.6) и комментариев (§3.7), составляют токены (§3.5), являющиеся терминальными символами синтаксической грамматики (§2.3).

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

Вводные символы a--b разделяются на токены (§3.5) как a, --, b, что не является частью любой грамматически корректной программы, даже если разбиение на токены a, -, -, b может быть частью грамматически корректной программы.

Без правила для > символов, два последовательных > скобки в типе, таком как List<List<String>>, будут разделены на токен сдвиг вправо с знаком >>, в то время как три последовательные > скобки в типе, таком как List<List<List<String>>>, будут разделяться на токен сдвига вправо без знака >>>. Хуже того, разбиение на токены четырёх или более последовательных > скобок в типе, таком как List<List<List<List<String>>>>, будет неоднозначным, так как различные комбинации токенов >, >> и >>> могли бы представлять >>>> символов.

3.3. Unicode-экранирование

Компилятор языка программирования Java ("компилятор Java") сначала распознаёт Unicode-экранирование в своём вводе, преобразуя ASCII-символы \u, за которыми следуют четыре шестнадцатеричных цифры, в единицу кода UTF-16 (§3.1) для указанного шестнадцатеричного значения, и оставляя все остальные символы без изменений. Для представления дополнительных символов требуются два последовательных Unicode-экранирования. Этот этап преобразования приводит к последовательности символов Unicode на входе.

UnicodeInputCharacter:
UnicodeEscape
RawInputCharacter
UnicodeEscape:
\ UnicodeMarker HexDigit HexDigit HexDigit HexDigit
UnicodeMarker:
u {u}
HexDigit:
(любой из)
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
RawInputCharacter:
любой символ Unicode

Здесь \, u и шестнадцатеричные цифры — всё ASCII-символы.

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

Например, исходный ввод "\\u2122=\u2122" приводит к одиннадцати символам " \ \ u 2 1 2 2 = ™ " (\u2122 — это кодировка Unicode символа ™).

Если допустимая \ не следует за u, то она рассматривается как RawInputCharacter и остаётся частью потока экранированного Unicode.

Если допустимая \ следует за u или более чем за одной u, и последняя u не следует за четырьмя шестнадцатеричными цифрами, то происходит ошибка времени компиляции.

Символ, созданный Unicode-экранированием, не участвует в дальнейших Unicode-экранированиях.

Например, исходный ввод \u005cu005a приводит к шести символам \ u 0 0 5 a, потому что 005c — значение Unicode для \. Это не приводит к символу Z, который является Unicode-символом 005a, потому что \, полученная из \u005c, не интерпретируется как начало дальнейшего Unicode-экранирования.

Язык программирования Java определяет стандартный способ преобразования программы, написанной на Unicode, в ASCII, который изменяет программу в форму, обрабатываемую ASCII-инструментами. Преобразование включает преобразование всех Unicode-экранирований в исходном тексте программы в ASCII путём добавления дополнительной u – например, \uxxxx превращается в \uuxxxx – одновременно с преобразованием не-ASCII-символов в исходном тексте в Unicode-экранирования, содержащие по одному u каждый.

Эта преобразованная версия так же приемлема для компилятора Java и представляет точно такую же программу. Точный исходный код Unicode может быть позже восстановлен из этой ASCII-формы путём преобразования каждой последовательности экранирования, где присутствует несколько u, в последовательность символов Unicode с одной u меньше, одновременно преобразуя каждую последовательность экранирования с одной u в соответствующий одиночный символ Unicode.

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

3.4. Разделители строк

Компилятор Java далее делит последовательность символов Unicode на строки, распознавая разделители строк.

LineTerminator:
символ ASCII LF (также известный как "новая строка")
символ ASCII CR (также известный как "возврат каретки")
символ ASCII CR, за которым следует символ ASCII LF
InputCharacter:
UnicodeInputCharacter но не CR или LF

Строки завершаются символами ASCII CR, или LF, или CR LF. Два символа CR, непосредственно за которыми следует LF, считаются одним разделителем строк, а не двумя.

Разделитель строки указывает завершение // формы комментария (§3.7).

Определяемые разделителями строк строки могут определять номера строк, генерируемые компилятором Java.

Результат — последовательность разделителей строк и символов ввода, которые являются терминальными символами для третьего этапа процесса токенизации.

3.5. Элементы ввода и токены

Символы ввода и разделители строк, полученные в результате обработки экранирования (§3.3), а затем распознавания строк ввода (§3.4), сводятся к последовательности элементов ввода.

Input:
{InputElement} [Sub]
InputElement:
WhiteSpace
Comment
Token
Token:
Identifier
Keyword
Literal
Separator
Operator
Sub:
символ ASCII SUB, также известный как "control-Z"

Те элементы ввода, которые не являются пробелами или комментариями, являются токенами. Токены являются терминальными символами синтаксической грамматики (§2.3).

Пробелы (§3.6) и комментарии (§3.7) могут служить для разделения токенов, которые, будучи смежными, могли бы быть проанализированы по-другому. Например, ASCII-символы - и = на входе могут образовывать операторный токен -= (§3.12), только если нет никаких вмещающихся пробелов или комментариев.

В качестве особой уступки для совместимости с некоторыми операционными системами, символ ASCII SUB (\u001a, или control-Z) игнорируется, если это последний символ в потоке экранированного ввода.

Рассмотрим два токена x и y в результирующем потоке ввода. Если x предшествует y, то мы говорим, что x находится слева от y, и что y находится справа от x.

Например, в этом простом фрагменте кода:

class Empty {
}

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

3.6. Пробелы

Пробелы определяются как ASCII-пробел, табуляция, символ перевода страницы и разделители строк (§3.4).

WhiteSpace:
ASCII-пробел
ASCII-табуляция
символ перевода страницы
LineTerminator

3.7. Комментарии

Существует два вида комментариев:

  • /* текст */

    Традиционный комментарий: весь текст от символов ASCII /* до символов ASCII */ игнорируется (как в C и C++).

  • // текст

    Комментарий в конце строки: весь текст от символов ASCII // до конца строки игнорируется (как в C++).

Комментарий:
TraditionalComment
EndOfLineComment
TraditionalComment:
/ * CommentTail
CommentTail:
* CommentTailStar
NotStar CommentTail
CommentTailStar:
/
* CommentTailStar
NotStarNotSlash CommentTail
NotStar:
СимволВвода но не *
РазделительСтрок
NotStarNotSlash:
СимволВвода но не * или /
РазделительСтрок
EndOfLineComment:
/ / {СимволВвода}

Эти правила подразумевают все следующие свойства:

  • Комментарии не вложены.

  • /* и */ не имеют особого значения в комментариях, начинающихся с //.

  • // не имеет особого значения в комментариях, начинающихся с /* или /**.

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

/* this comment /* // /** ends here: */

Лексическая грамматика подразумевает, что комментарии не встречаются внутри символьных (§3.10.4) или строковых (§3.10.5) литералов.

3.8. Идентификаторы

Идентификатор — это последовательность неограниченной длины символов Java и цифр Java, первая из которых должна быть символом Java.

Идентификатор:
IdentifierChars но не Ключевое слово или Булево значение или NullLiteral
IdentifierChars:
БукваJava {БукваИлиЦифраJava}
БукваJava:
любой символ Unicode, являющийся "буква Java"
БукваИлиЦифраJava:
любой символ Unicode, являющийся "буква-или-цифра Java"

Символ "буква Java" — это символ, для которого метод Character.isJavaIdentifierStart(int) возвращает true.

Символ "буква-или-цифра Java" — это символ, для которого метод Character.isJavaIdentifierPart(int) возвращает true.

К "буквам Java" относятся прописные и строчные ASCII латинские буквы A-Z (\u0041-\u005a), и a-z (\u0061-\u007a), и, по историческим причинам, символ ASCII доллара ($, или \u0024) и подчёркивание (_, или \u005f). Символ доллара должен использоваться только в автоматически сгенерированном исходном коде или, редко, для доступа к существующим именам в старых системах. Подчёркивание может использоваться в идентификаторах, состоящих из двух или более символов, но не может использоваться в качестве односимвольного идентификатора из-за того, что является ключевым словом.

К "цифрам Java" относятся ASCII цифры 0-9 (\u0030-\u0039).

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

Идентификатор не может иметь такое же написание (последовательность символов Unicode), как ключевое слово (§3.9), булево значение (§3.10.3) или нулевое значение (§3.10.7), в противном случае возникает ошибка компиляции.

Два идентификатора одинаковы только если, после игнорирования игнорируемых символов, идентификаторы имеют одинаковый символ Unicode для каждой буквы или цифры. Игнорируемый символ — это символ, для которого метод Character.isIdentifierIgnorable(int) возвращает true. Идентификаторы, имеющие одинаковый внешний вид, могут быть различными.

Например, идентификаторы, состоящие из одной буквы LATIN CAPITAL LETTER A (A, \u0041), LATIN SMALL LETTER A (a, \u0061), GREEK CAPITAL LETTER ALPHA (A, \u0391), CYRILLIC SMALL LETTER A (a, \u0430) и MATHEMATICAL BOLD ITALIC SMALL A (a, \ud835\udc82) — все разные.

Составные символы Unicode отличаются от их канонических эквивалентов, полученных разложением. Например, LATIN CAPITAL LETTER A ACUTE (Á, \u00c1) отличается от LATIN CAPITAL LETTER A (A, \u0041), за которым сразу следует NON-SPACING ACUTE (´, \u0301) в идентификаторах. См. Стандарт Unicode, раздел 3.11 «Формы нормализации».

Примеры идентификаторов:

  • String

  • i3

  • αρετη

  • MAX_VALUE

  • isLetterOrDigit

Идентификатор типа — это идентификатор, не являющийся последовательностью символов var.

TypeIdentifier:
Идентификатор но не var

Идентификаторы типов используются в определенных контекстах, связанных с объявлением или использованием типов. Например, имя класса должно быть TypeIdentifier, поэтому объявление класса с именем var недопустимо (§8.1).

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

51 последовательность символов, образованных из букв ASCII, зарезервированы для использования в качестве ключевых слов и не могут использоваться в качестве идентификаторов (§3.8).

Ключевое слово:
(одно из)
abstract   continue   for          new         switch
assert     default    if           package     synchronized
boolean    do         goto         private     this
break      double     implements   protected   throw
byte       else       import       public      throws
case       enum       instanceof   return      transient
catch      extends    int          short       try
char       final      interface    static      void
class      finally    long         strictfp    volatile
const      float      native       super       while
_ (underscore)

Ключевые слова const и goto зарезервированы, даже если они в настоящее время не используются. Это может позволить компилятору Java создавать более информативные сообщения об ошибках, если эти ключевые слова C++ неправильно появятся в программах.

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

  • true и false не являются ключевыми словами, а скорее булевыми литералами (§3.10.3).

  • null не является ключевым словом, а скорее нулевым литералом (§3.10.7).

  • var не является ключевым словом, а скорее идентификатором со специальным значением, как тип объявления локальной переменной (§14.4, §14.14.1, §14.14.2, §14.20.3) и тип формального параметра лямбды (§15.27.1).

Ещё десять последовательностей символов являются зарезервированными ключевыми словами: open, module, requires, transitive, exports, opens, to, uses, provides и with. Эти последовательности символов распознаются как ключевые слова только в тех случаях, когда они появляются как терминалы в производных ModuleDeclaration, ModuleDirective и RequiresModifier (§7.7). В остальных случаях они распознаются как идентификаторы для обеспечения совместимости с программами, написанными до введения зарезервированных ключевых слов. Существует одно исключение: непосредственно справа от последовательности символов requires в производной ModuleDirective последовательность символов transitive распознаётся как ключевое слово, если за ней не следует разделитель, в противном случае она распознаётся как идентификатор.

3.10. Литералы

A литерал — это представление значения примитивного типа в исходном коде (§4.2), типа String (§4.3.3) или типа null (§4.1).

Литерал:
Целочисленная литерал
Литерал с плавающей точкой
Логическая литерал
Символьная литерал
Строковая литерал
Литерал null

3.10.1. Целочисленные литералы

Целочисленная литерал может быть представлена в десятичной (основание 10), шестнадцатеричной (основание 16), восьмеричной (основание 8) или двоичной (основание 2) форме.

Целочисленная литерал:
Десятичная целочисленная литерал
Шестнадцатеричная целочисленная литерал
Восьмеричная целочисленная литерал
Двоичная целочисленная литерал
Десятичная целочисленная литерал:
Десятичная цифра [Суффикс целочисленного типа]
Шестнадцатеричная целочисленная литерал:
Шестнадцатеричная цифра [Суффикс целочисленного типа]
Восьмеричная целочисленная литерал:
Восьмеричная цифра [Суффикс целочисленного типа]
Двоичная целочисленная литерал:
Двоичная цифра [Суффикс целочисленного типа]
Суффикс целочисленного типа:
(один из)
l L

Целочисленная литерал имеет тип long, если она имеет суффикс с латинской буквой L или l (ell); в противном случае ее тип — int (§4.2.1).

Суффикс L предпочтительнее, поскольку букву l (ell) часто трудно отличить от цифры 1 (один).

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

В шестнадцатеричной или двоичной литерале целое число обозначается только цифрами после символов 0x или 0b и перед любым суффиксом типа. Поэтому подчеркивания не могут появляться непосредственно после 0x или 0b, или после последней цифры в числе.

В десятичной или восьмеричной литерале целое число обозначается всеми цифрами в литерале перед любым суффиксом типа. Поэтому подчеркивания не могут появляться перед первой цифрой или после последней цифры в числе. Подчеркивания могут появляться после начальной 0 в восьмеричной цифре (поскольку 0 — это цифра, обозначающая часть целого числа) и после начальной отличной от нуля цифры в десятичной литерале, отличной от нуля.

Десятичная цифра — это либо единственная ASCII-цифра 0, представляющая ноль, или состоит из ASCII-цифры от 1 до 9, за которой необязательно следуют одна или несколько ASCII-цифр от 0 до 9, чередующиеся с подчеркиваниями, представляющими положительное целое число.

Десятичная цифра:
0
Цифра, отличная от нуля [Цифры]
Цифра, отличная от нуля Подчеркивания Цифры
Цифра, отличная от нуля:
(одна из)
1 2 3 4 5 6 7 8 9
Цифры:
Цифра
Цифра [Цифры и подчеркивания] Цифра
Цифра:
0
Цифра, отличная от нуля
Цифры и подчеркивания:
Цифра или подчеркивание {Цифра или подчеркивание}
Цифра или подчеркивание:
Цифра
_
Подчеркивания:
_ {_}

Шестнадцатеричная цифра состоит из начальных ASCII-символов 0x или 0X, за которыми следуют одна или несколько ASCII-шестнадцатеричных цифр, перемежающиеся с подчеркиваниями, и может представлять положительное, нулевое или отрицательное целое число.

Шестнадцатеричные цифры со значениями от 10 до 15 представлены ASCII-буквами a до f или A до F соответственно; каждая буква, используемая как шестнадцатеричная цифра, может быть заглавной или строчной.

Шестнадцатеричная цифра:
0 x Шестнадцатеричные цифры
0 X Шестнадцатеричные цифры
Шестнадцатеричные цифры:
Шестнадцатеричная цифра
Шестнадцатеричная цифра [Шестнадцатеричные цифры и подчеркивания] Шестнадцатеричная цифра
Шестнадцатеричная цифра:
(одна из)
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
Шестнадцатеричные цифры и подчеркивания:
Шестнадцатеричная цифра или подчеркивание {Шестнадцатеричная цифра или подчеркивание}
Шестнадцатеричная цифра или подчеркивание:
Шестнадцатеричная цифра
_

Производство шестнадцатеричной цифры выше взято из §3.3.

Восьмеричная цифра состоит из ASCII-цифры 0, за которой следуют одна или несколько ASCII-цифр от 0 до 7, перемежающиеся с подчеркиваниями, и может представлять положительное, нулевое или отрицательное целое число.

Восьмеричная цифра:
0 Восьмеричные цифры
0 Подчеркивания Восьмеричные цифры
Восьмеричные цифры:
Восьмеричная цифра
Восьмеричная цифра [Восьмеричные цифры и подчеркивания] Восьмеричная цифра
Восьмеричная цифра:
(одна из)
0 1 2 3 4 5 6 7
Восьмеричные цифры и подчеркивания:
Восьмеричная цифра или подчеркивание {Восьмеричная цифра или подчеркивание}
Восьмеричная цифра или подчеркивание:
Восьмеричная цифра
_

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

Двоичная цифра состоит из начальных ASCII-символов 0b или 0B, за которыми следуют одна или несколько ASCII-цифр 0 или 1, перемежающиеся с подчеркиваниями, и может представлять положительное, нулевое или отрицательное целое число.

BinaryNumeral:
0 b BinaryDigits
0 B BinaryDigits
BinaryDigits:
BinaryDigit
BinaryDigit [BinaryDigitsAndUnderscores] BinaryDigit
BinaryDigit:
(один из)
0 1
BinaryDigitsAndUnderscores:
BinaryDigitOrUnderscore {BinaryDigitOrUnderscore}
BinaryDigitOrUnderscore:
BinaryDigit
_

Наибольшее десятичное литерал типа int равно 2147483648 (231).

Все десятичные литералы от 0 до 2147483647 могут появиться в любом месте, где может появиться литерал типа int. Десятичный литерал 2147483648 может появиться только в качестве операнда унарного минуса - (§15.15.4).

Ошибка времени компиляции, если десятичный литерал 2147483648 появляется в любом месте, кроме как в качестве операнда унарного минуса; или если десятичный литерал типа int больше, чем 2147483648 (231).

Наибольшие положительные шестнадцатеричные, восьмеричные и двоичные литералы типа int — каждый из которых представляет десятичное значение 2147483647 (231-1) — соответственно:

  • 0x7fff_ffff,

  • 0177_7777_7777, и

  • 0b0111_1111_1111_1111_1111_1111_1111_1111

Наименьшие шестнадцатеричные, восьмеричные и двоичные литералы типа int — каждый из которых представляет десятичное значение -2147483648 (-231) — соответственно:

  • 0x8000_0000,

  • 0200_0000_0000, и

  • 0b1000_0000_0000_0000_0000_0000_0000_0000

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

  • 0xffff_ffff,

  • 0377_7777_7777, и

  • 0b1111_1111_1111_1111_1111_1111_1111_1111

Ошибка времени компиляции, если шестнадцатеричный, восьмеричный или двоичный литерал int не помещается в 32 бита.

Наибольшее десятичное литерал типа long равно 9223372036854775808L (263).

Все десятичные литералы от 0L до 9223372036854775807L могут появиться в любом месте, где может появиться литерал long. Десятичный литерал 9223372036854775808L может появиться только в качестве операнда унарного минуса - (§15.15.4).

Ошибка времени компиляции, если десятичный литерал 9223372036854775808L появляется в любом месте, кроме как в качестве операнда унарного минуса; или если десятичный литерал типа long больше, чем 9223372036854775808L (263).

Наибольшие положительные шестнадцатеричные, восьмеричные и двоичные литералы типа long — каждый из которых представляет десятичное значение 9223372036854775807L (263-1) — соответственно:

  • 0x7fff_ffff_ffff_ffffL,

  • 07_7777_7777_7777_7777_7777L, и

  • 0b0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L

Наименьшие шестнадцатеричные, восьмеричные и двоичные литералы типа long — каждый из которых представляет десятичное значение -9223372036854775808L (-263) — соответственно:

  • 0x8000_0000_0000_0000L, и

  • 010_0000_0000_0000_0000_0000L, и

  • 0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000L

Следующие шестнадцатеричные, восьмеричные и двоичные литералы представляют десятичное значение -1L:

  • 0xffff_ffff_ffff_ffffL,

  • 017_7777_7777_7777_7777_7777L, и

  • 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L

Ошибка времени компиляции, если шестнадцатеричный, восьмеричный или двоичный литерал long не помещается в 64 бита.

Примеры литералов int:

0    2    0372    0xDada_Cafe    1996    0x00_FF__00_FF

Примеры литералов long:

0l    0777L    0x100000000L    2_147_483_648L    0xC0B0L

3.10.2. Числа с плавающей точкой

Литерал с плавающей точкой состоит из следующих частей: целая часть, десятичная или шестнадцатеричная точка (представленная символом ASCII точки), дробная часть, порядок и суффикс типа.

Литерал с плавающей точкой может быть представлен в десятичной (основание 10) или шестнадцатеричной (основание 16) форме.

Для десятичных литералов с плавающей точкой требуется хотя бы одна цифра (в целой или дробной части) и либо десятичная точка, либо порядок, либо суффикс типа float. Все остальные части являются необязательными. Порядок, если он присутствует, обозначается символами ASCII e или E, за которыми следует необязательно со знаком целое число.

Для шестнадцатеричных литералов с плавающей точкой требуется хотя бы одна цифра (в целой или дробной части), порядок является обязательным, а суффикс типа float — необязательным. Порядок обозначается символами ASCII p или P, за которыми следует необязательно со знаком целое число.

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

FloatingPointLiteral:
DecimalFloatingPointLiteral
HexadecimalFloatingPointLiteral
DecimalFloatingPointLiteral:
Digits . [Digits] [ExponentPart] [FloatTypeSuffix]
. Digits [ExponentPart] [FloatTypeSuffix]
Digits ExponentPart [FloatTypeSuffix]
Digits [ExponentPart] FloatTypeSuffix
ExponentPart:
ExponentIndicator SignedInteger
ExponentIndicator:
(один из)
e E
SignedInteger:
[Sign] Digits
Sign:
(один из)
+ -
FloatTypeSuffix:
(один из)
f F d D
HexadecimalFloatingPointLiteral:
HexSignificand BinaryExponent [FloatTypeSuffix]
HexSignificand:
HexNumeral [.]
0 x [HexDigits] . HexDigits
0 X [HexDigits] . HexDigits
BinaryExponent:
BinaryExponentIndicator SignedInteger
BinaryExponentIndicator:
(один из)
p P

Литерал с плавающей точкой имеет тип float, если он имеет суффикс символами ASCII F или f; в противном случае его тип — double, и он может быть необязательно снабжён суффиксом символами ASCII D или d (§4.2.3).

Элементы типов float и double представляют собой те значения, которые могут быть представлены с помощью 32-битного одноточного и 64-битного двойного точного форматов чисел с плавающей точкой IEEE 754 соответственно.

Подробное описание правильного преобразования входных данных из строкового представления числа с плавающей точкой в Юникоде во внутреннее представление числа с плавающей точкой в формате IEEE 754 приведено для методов valueOf класса Float и класса Double пакета java.lang.

Наибольший положительный конечный литерал типа float равен 3.4028235e38f.

Наименьший положительный конечный ненулевой литерал типа float равен 1.40e-45f.

Наибольший положительный конечный литерал типа double равен 1.7976931348623157e308.

Наименьший положительный конечный ненулевой литерал типа double равен 4.9e-324.

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

Программа может представлять бесконечности без возникновения ошибки во время компиляции, используя константные выражения, такие как 1f/0f или -1d/0d, или используя предварительно определённые константы POSITIVE_INFINITY и NEGATIVE_INFINITY классов Float и Double.

Если ненулевой литерал с плавающей точкой слишком мал, так что при округленном преобразовании в его внутреннее представление он становится нулём, то возникает ошибка во время компиляции.

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

Предварительно определённые константы, представляющие значения Не Число (NaN), определены в классах Float и Double как Float.NaN и Double.NaN.

Примеры литералов float:

1e1f    2.f    .3f    0f    3.14f    6.022137e+23f

Примеры литералов double:

1e1    2.    .3    0.0    3.14    1e-9d    1e137

3.10.3. Булевы литералы

Тип boolean имеет два значения, представленные булевыми литералами true и false, сформированными из символов ASCII.

BooleanLiteral:
(один из)
true false

Булевый литерал всегда имеет тип boolean (§4.2.5).

3.10.4. Литералы символов

Литерал символа выражается как символ или последовательность управляющих символов (§3.10.6), заключённые в одинарные кавычки ASCII. (Символ одинарной кавычки или апострофа – это \u0027.)

CharacterLiteral:
' SingleCharacter '
' EscapeSequence '
SingleCharacter:
InputCharacter но не ' или \

См. §3.10.6 для определения EscapeSequence.

Литералы символов могут представлять только единицы кодирования UTF-16 (§3.1), т.е. они ограничены значениями от \u0000 до \uffff. Дополнительные символы должны быть представлены либо как пара суррогатов в последовательности char, либо как целое число, в зависимости от API, с которым они используются.

Литерал символа всегда имеет тип char (§4.2.1).

Ошибка компиляции, если символ, следующий за SingleCharacter или EscapeSequence, отличается от '.

Ошибка компиляции, если разделитель строки (§3.4) появляется после открывающей ' и перед закрывающей '.

Как указано в §3.4, символы CR и LF никогда не являются InputCharacter; каждый из них распознаётся как LineTerminator.

Ниже приведены примеры литералов char:

  • 'a'

  • '%'

  • '\t'

  • '\\'

  • '\''

  • '\u03a9'

  • '\uFFFF'

  • '\177'

  • '™'

Поскольку эскейпы Unicode обрабатываются очень рано, неверно писать '\u000a' для литерала символа, значение которого — перевод строки (LF); эскейп Unicode \u000a преобразуется в фактический перевод строки на этапе 1 (§3.3), а перевод строки становится LineTerminator на этапе 2 (§3.4), поэтому литерал символа недействителен на этапе 3. Вместо этого следует использовать последовательность управляющих символов '\n' (§3.10.6). Аналогично, неверно писать '\u000d' для литерала символа, значение которого — возврат каретки (CR). Вместо этого используйте '\r'.

В C и C++ литерал символа может содержать представление более одного символа, но значение такого литерала символа определяется реализацией. В языке программирования Java литерал символа всегда представляет ровно один символ.

3.10.5. Строковые литералы

Строковый литерал состоит из нуля или более символов, заключённых в двойные кавычки. Символы могут быть представлены последовательностями управляющих символов (§3.10.6) — одна последовательность управляющих символов для символов в диапазоне U+0000 до U+FFFF, две последовательности управляющих символов для суррогатных единиц кодирования UTF-16 символов в диапазоне U+010000 до U+10FFFF.

StringLiteral:
" {StringCharacter} "
StringCharacter:
InputCharacter но не " или \
EscapeSequence

См. §3.10.6 для определения EscapeSequence.

Строковый литерал всегда имеет тип String (§4.3.3).

Ошибка компиляции, если разделитель строки появляется после открывающей " и перед закрывающей соответствующей ".

Как указано в §3.4, символы CR и LF никогда не являются InputCharacter; каждый из них распознаётся как LineTerminator.

Длинный строковый литерал всегда можно разбить на более короткие фрагменты и записать как (возможно, заключённое в скобки) выражение с использованием оператора конкатенации строк + (§15.18.1).

Ниже приведены примеры строковых литералов:

""                    // the empty string
"\""                  // a string containing " alone
"This is a string"    // a string containing 16 characters
"This is a " +        // actually a string-valued constant expression,
    "two-line string"    // formed from two string literals

Поскольку эскейпы Unicode обрабатываются очень рано, неверно писать "\u000a" для строкового литерала, содержащего единственный перевод строки (LF); эскейп Unicode \u000a преобразуется в фактический перевод строки на этапе 1 (§3.3), а перевод строки становится LineTerminator на этапе 2 (§3.4), поэтому строковый литерал недействителен на этапе 3. Вместо этого следует написать "\n" (§3.10.6). Аналогично, неверно писать "\u000d" для строкового литерала, содержащего единственную возврат каретки (CR). Вместо этого используйте "\r". Наконец, невозможно записать "\u0022" для строкового литерала, содержащего двойную кавычку (").

Строковый литерал — это ссылка на экземпляр класса String (§4.3.1, §4.3.3).

Более того, строковый литерал всегда ссылается на один и тот же экземпляр класса String. Это происходит потому, что строковые литералы — или, более общо, строки, которые являются значениями константных выражений (§15.28) — «интернациируются», чтобы использовать уникальные экземпляры, используя метод String.intern (§12.5).

Пример 3.10.5-1. Строковые литералы

Программа, состоящая из блока компиляции (§7.3):

package testPackage;
class Test {
    public static void main(String[] args) {
        String hello = "Hello", lo = "lo";
        System.out.println(hello == "Hello");
        System.out.println(Other.hello == hello);
        System.out.println(other.Other.hello == hello);
        System.out.println(hello == ("Hel"+"lo"));
        System.out.println(hello == ("Hel"+lo));
        System.out.println(hello == ("Hel"+lo).intern());
    }
}
class Other { static String hello = "Hello"; }

и блок компиляции:

package other;
public class Other { public static String hello = "Hello"; }

выводит:

true
true
true
true
false
true

Этот пример иллюстрирует шесть моментов:

  • Строковые литералы в одном классе и пакете представляют ссылки на один и тот же объект String (§4.3.1).

  • Строковые литералы в разных классах в одном пакете представляют ссылки на один и тот же объект String.

  • Строковые литералы в разных классах в разных пакетах также представляют ссылки на один и тот же объект String.

  • Строки, сконкатенированные из константных выражений (§15.28), вычисляются во время компиляции и затем обрабатываются так, как будто они являются литералами.

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

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


3.10.6. Последовательности экранирования для символьных и строковых литералов

Символьные и строковые последовательности экранирования позволяют представлять некоторые неграфические символы без использования Unicode-экранирования, а также символы одиночной кавычки, двойной кавычки и обратной косой черты в символьных литералах (§3.10.4) и строковых литералах (§3.10.5).

EscapeSequence:
\ b (возврат на позицию BS, Unicode \u0008)
\ t (горизонтальная табуляция HT, Unicode \u0009)
\ n (перевод строки LF, Unicode \u000a)
\ f (формат страницы FF, Unicode \u000c)
\ r (возврат каретки CR, Unicode \u000d)
\ " (двойная кавычка, Unicode ")
\ ' (одинарная кавычка, Unicode ')
\ \ (обратная косая черта, Unicode \)
OctalEscape (восьмеричное значение, Unicode \u0000 до \u00ff)
OctalEscape:
\ OctalDigit
\ OctalDigit OctalDigit
\ ZeroToThree OctalDigit OctalDigit
OctalDigit:
(один из)
0 1 2 3 4 5 6 7
ZeroToThree:
(один из)
0 1 2 3

Производство OctalDigit выше взято из §3.10.1.

Ошибка компиляции, если символ, следующий за обратной косой чертой в последовательности экранирования, не является ASCII b, t, n, f, r, ", ', \, 0, 1, 2, 3, 4, 5, 6 или 7. Экранирование Unicode \u обрабатывается ранее (§3.3).

Восьмеричные экранирования представлены для совместимости с C, но могут выражать только значения Unicode от \u0000 до \u00FF, поэтому Unicode-экранирование обычно предпочтительнее.

3.10.7. Литерал null

Тип null имеет одно значение — нулевую ссылку, представленную литералом null null, который формируется из ASCII-символов.

NullLiteral:
null

Литерал null всегда относится к типу null (§4.1).

3.11. Разделители

Двенадцать токенов, образованных из ASCII-символов, являются разделителями (знаками препинания).

Separator:
(один из)
(   )   {   }   [   ]   ;   ,   .   ...   @   ::

3.12. Операторы

38 токенов, образованных из ASCII-символов, являются операторами.

Operator:
(один из)
=   >   <   !   ~   ?   :   ->
==  >=  <=  !=  &&  ||  ++  --
+   -   *   /   &   |   ^   %   <<   >>   >>>
+=  -=  *=  /=  &=  |=  ^=  %=  <<=  >>=  >>>=

© Oracle and/or its affiliates. All rights reserved.
Licensed under the Oracle Technology Network License Agreement.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API