Spec-Zone.ru › Java Language Specification 7

Глава 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), но предоставляются лексические преобразования (§3.2), чтобы можно было использовать экранирование Unicode (§3.3) для вставки любых символов Unicode, используя только символы ASCII. Определены разделители строк (§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 до версии 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).

Стандарт 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).

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

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

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

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


СимволВводаUnicode:
ЭкранированиеUnicode
СимволВводаНеобработанный

ЭкранированиеUnicode:
\ МаркерUnicode ШестнадцатеричнаяЦифра ШестнадцатеричнаяЦифра ШестнадцатеричнаяЦифра ШестнадцатеричнаяЦифра

МаркерUnicode:
u
МаркерUnicode u

СимволВводаНеобработанный:
любой символ Unicode

ШестнадцатеричнаяЦифра: один из
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

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

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

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

Если допустимое \ не сопровождается u, то оно обрабатывается как СимволВводаНеобработанный и остаётся частью закодированного потока 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 на строки, распознавая разделители строк.


РазделительСтроки:
ASCII-символ LF, также известный как «новая строка»
ASCII-символ CR, также известный как «возврат каретки»
ASCII-символ CR, за которым следует ASCII-символ LF

СимволВвода:
СимволВводаUnicode но не CR или LF

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

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

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

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

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

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


Ввод:
ЭлементыВводаопт Подопт

ЭлементыВвода:
ЭлементВвода
ЭлементыВвода ЭлементВвода

ЭлементВвода:
Пробел
Комментарий
Токен

Токен:
Идентификатор
КлючевоеСлово
Литерал
Разделитель
Оператор

Под:
ASCII-символ SUB, также известный как «управляющий символ Z»

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

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

Как специальное соглашение для совместимости с определёнными операционными системами, ASCII-символ SUB (\u001a, или управляющий символ Z) игнорируется, если он является последним символом в закодированном потоке ввода.

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

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

class Empty {
}

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

3.6. Пробелы

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


Пробел:
ASCII-символ SP, также известный как «пробел»
ASCII-символ HT, также известный как «горизонтальная табуляция»
ASCII-символ FF, также известный как «перевод страницы»
РазделительСтроки

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

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

  • /* текст */

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

  • // текст

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


Комментарий:
ТрадиционныйКомментирование
КомментарийНаКонецСтроки

ТрадиционныйКомментирование:
/ * ХвостКомментирования

КомментарийНаКонецСтроки:
/ / СимволыВСтрокеопционально

ХвостКомментирования:
* ЗвездаХвостКомментирования
НеЗвезда ХвостКомментирования

ЗвездаХвостКомментирования:
/
* ЗвездаХвостКомментирования
НеЗвездаНеСлеш ХвостКомментирования

НеЗвезда:
ВходнойСимвол но не *
ТерминаторСтроки

НеЗвездаНеСлеш:
ВходнойСимвол но не * или /
ТерминаторСтроки

СимволыВСтроке:
ВходнойСимвол
СимволыВСтроке ВходнойСимвол

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

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

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

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

В результате текст:

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

является одним полным комментарием.

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

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

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


Идентификатор:
СимволыИдентификатора но не КлючевоеСлово или БулевоЛитерал или ЛитералNull

СимволыИдентификатора:
JavaБуква
СимволыИдентификатора JavaБукваИлиЦифра

JavaБуква:
любой символ Юникода, который является Java буквой (см. ниже)

JavaБукваИлиЦифра:
любой символ Юникода, который является Java буквой или цифрой (см. ниже)

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

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

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

«Java цифры» включают ASCII цифры 0-9 (\u0030-\u0039).

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

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

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

Например, идентификаторы, состоящие из одиночных букв ЗАГЛАВНАЯ ЛАТИНСКАЯ БУКВА A (A, \u0041), ПРОПИСНАЯ ЛАТИНСКАЯ БУКВА A (a, \u0061), ГРЕЧЕСКАЯ ЗАГЛАВНАЯ БУКВА АЛЬФА (A, \u0391), КИРИЛЛИЧЕСКАЯ МАЛЕНЬКАЯ БУКВА А (a, \u0430) и МАТЕМАТИЧЕСКАЯ ЖИРНАЯ КУРСОВАЯ МАЛЕНЬКАЯ БУКВА A (a, \ud835\udc82) все разные.

Составные символы Юникода отличаются от своих канонически эквивалентных разложенных символов. Например, ЗАГЛАВНАЯ ЛАТИНСКАЯ БУКВА A С ОСТРЫМ АКЦЕНТОМ (Á, \u00c1) отличается от ЗАГЛАВНОЙ ЛАТИНСКОЙ БУКВЫ A (A, \u0041), за которой сразу следует НЕРАЗРЫВНЫЙ ОСТРЫЙ АКЦЕНТ (´, \u0301) в идентификаторах. См. Стандарт Юникода, раздел 3.11 «Формы нормализации».

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

  • String

  • i3

  • αρετη

  • MAX_VALUE

  • isLetterOrDigit

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

50 последовательностей символов, образованных 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

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

Хотя true и false могут казаться ключевыми словами, технически они булевы литералы (§3.10.3). Аналогично, хотя null может казаться ключевым словом, технически это литерал null (§3.10.7).

3.10. Литералы

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


Литерал:
ЦелочисленныйЛитерал
ВещественныйЛитерал
БулевоЛитерал
СимвольныйЛитерал
СтроковыйЛитерал
ЛитералNull

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

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


IntegerLiteral:
DecimalIntegerLiteral
HexIntegerLiteral
OctalIntegerLiteral
BinaryIntegerLiteral

DecimalIntegerLiteral:
DecimalNumeral IntegerTypeSuffixopt

HexIntegerLiteral:
HexNumeral IntegerTypeSuffixopt

OctalIntegerLiteral:
OctalNumeral IntegerTypeSuffixopt

BinaryIntegerLiteral:
BinaryNumeral IntegerTypeSuffixopt

IntegerTypeSuffix: одно из
l L

Целочисленный литерал имеет тип long, если он завершается ASCII-символом 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, чередующиеся с подчеркиваниями, представляющими положительное целое число.


DecimalNumeral:
0
NonZeroDigit Digitsopt
NonZeroDigit Underscores Digits

Digits:
Digit
Digit DigitsAndUnderscoresopt Digit

Digit:
0
NonZeroDigit

NonZeroDigit: одно из
1 2 3 4 5 6 7 8 9

DigitsAndUnderscores:
DigitOrUnderscore
DigitsAndUnderscores DigitOrUnderscore

DigitOrUnderscore:
Digit
_

Underscores:
_
Underscores _

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

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


HexNumeral:
0 x HexDigits
0 X HexDigits

HexDigits:
HexDigit
HexDigit HexDigitsAndUnderscoresopt HexDigit

HexDigit: одно из
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

HexDigitsAndUnderscores:
HexDigitOrUnderscore
HexDigitsAndUnderscores HexDigitOrUnderscore

HexDigitOrUnderscore:
HexDigit
_

Производство HexDigit выше взято из §3.3.

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


OctalNumeral:
0 OctalDigits
0 Underscores OctalDigits

OctalDigits:
OctalDigit
OctalDigit OctalDigitsAndUnderscoresopt OctalDigit

OctalDigit: одно из
0 1 2 3 4 5 6 7

OctalDigitsAndUnderscores:
OctalDigitOrUnderscore
OctalDigitsAndUnderscores OctalDigitOrUnderscore

OctalDigitOrUnderscore:
OctalDigit
_

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

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


BinaryNumeral:
0 b BinaryDigits
0 B BinaryDigits

BinaryDigits:
BinaryDigit
BinaryDigit BinaryDigitsAndUnderscoresopt BinaryDigit

BinaryDigit: одно из
0 1

BinaryDigitsAndUnderscores:
BinaryDigitOrUnderscore
BinaryDigitsAndUnderscores BinaryDigitOrUnderscore

BinaryDigitOrUnderscore:
BinaryDigit
_

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

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

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

Наибольшие положительные шестнадцатеричные, восьмеричные и двоичные литералы типа 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 литерал.

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

Наибольшие положительные шестнадцатеричные, восьмеричные и двоичные литералы типа 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 . Digitsopt ExponentPartopt FloatTypeSuffixopt
. Digits ExponentPartopt FloatTypeSuffixopt
Digits ExponentPart FloatTypeSuffixopt
Digits ExponentPartopt FloatTypeSuffix

ExponentPart:
ExponentIndicator SignedInteger

ExponentIndicator: один из
e E

SignedInteger:
Signopt Digits

Sign: один из
+ -

FloatTypeSuffix: один из
f F d D


HexadecimalFloatingPointLiteral:
HexSignificand BinaryExponent FloatTypeSuffixopt

HexSignificand:
HexNumeral
HexNumeral .
0 x HexDigitsopt . HexDigits
0 X HexDigitsopt . HexDigits

BinaryExponent:
BinaryExponentIndicator SignedInteger

BinaryExponentIndicator:один из
p P

Литерал с плавающей точкой имеет тип float, если он имеет суффикс F или f; в противном случае его тип — double, и он может необязательно иметь суффикс 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.

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

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

Предопределённые константы, представляющие значения «Не число», определены в классах 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

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

3.10.4. Символьные литералы

Символьный литерал выражается как символ или последовательность escape (§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'

  • 'Ω'

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

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

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

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


StringLiteral:
" StringCharactersopt "

StringCharacters:
StringCharacter
StringCharacters 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-escape-последовательности обрабатываются очень рано, неправильно использовать "\u000a" для строкового литерала, содержащего один символ новой строки (LF); Unicode-escape \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.

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

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

package testPackage;
class Test {
    public static void main(String[] args) {
        String hello = "Hello", lo = "lo";
        System.out.print((hello == "Hello") + " ");
        System.out.print((Other.hello == hello) + " ");
        System.out.print((other.Other.hello == hello) + " ");
        System.out.print((hello == ("Hel"+"lo")) + " ");
        System.out.print((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

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

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

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

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

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

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

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


3.10.6. Escape-последовательности для символьных и строковых литералов

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


EscapeSequence:
\ b /* \u0008: backspace BS */
\ t /* \u0009: табуляция HT */
\ n /* \u000a: перевод строки LF */
\ f /* \u000c: форма подачи FF */
\ r /* \u000d: возврат каретки CR */
\ " /* \u0022: двойная кавычка " */
\ ' /* \u0027: одинарная кавычка ' */
\ \ /* \u005c: обратная косая черта \ */
OctalEscape /* \u0000 по \u00ff: из восьмеричного значения */

OctalEscape:
\ OctalDigit
\ OctalDigit OctalDigit
\ ZeroToThree OctalDigit OctalDigit

OctalDigit: один из
0 1 2 3 4 5 6 7

ZeroToThree: один из
0 1 2 3

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

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

3.10.7. Литерал null

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


NullLiteral:
null

Литерал null всегда имеет тип null (§4.1).

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

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


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

3.12. Операторы

37 токенов являются операторами, образованными из 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