Spec-Zone.ru › Java Language Specification 8

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

Оглавление

3.1. Юникод
3.2. Лексические преобразования
3.3. Экранирование Юникода
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.

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

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

3.1. Юникод

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

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

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

Стандарт Юникод изначально разрабатывался как кодировка символов с фиксированной шириной 16 бит. Позже он был изменён, чтобы позволить символы, представление которых требует более 16 бит. Диапазон допустимых кодовых точек теперь от U+0000 до U+10FFFF, используя шестнадцатеричное обозначение U+n. Символы, кодовые точки которых больше U+FFFF, называются дополнительными символами. Для представления всего диапазона символов, используя только 16-битные единицы, стандарт Юникод определяет кодировку 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 (или экранирования Юникода (§3.3), которые приводят к символам ASCII).

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

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

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

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

  2. Преобразование потока Юникода, полученного на шаге 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:
InputCharacter но не *
LineTerminator
NotStarNotSlash:
InputCharacter но не * или /
LineTerminator
EndOfLineComment:
/ / {InputCharacter}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Например, идентификаторы, состоящие из одиночных букв 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

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. Литералы

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

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

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

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

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

Целочисленный литерал имеет тип long, если он снабжён суффиксом ASCII-буквой L или l (элл); иначе он имеет тип int (§4.2.1).

Рекомендуется использовать суффикс L, потому что букву l (элл) часто трудно отличить от цифры 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:
(один из)
+ -
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 представляют собой значения, которые могут быть представлены в формате чисел с плавающей точкой IEEE 754 с одинарной точностью (32 бита) и двойной точностью (64 бита) соответственно.

Подробности правильного преобразования строки Unicode, представляющей число с плавающей точкой, во внутреннее двоичное представление 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.

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

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

Предварительно определённые константы, представляющие значения Not-a-Number, определены в классах 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.

Пример 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. Последовательности экранирования для символьных и строковых литералов

Последовательности экранирования символов и строк позволяют представить некоторые неграфические символы без использования 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 \u0022)
\ ' (одинарная кавычка ', Unicode \u0027)
\ \ (обратная косая черта \, Unicode \u005c)
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