Какова семантика Java у экранированного числа в символьном литерале, например '\ 15'?

85

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

int a='\15';
System.out.println(a);

это распечатывает 13;

int a='\25';
System.out.println(a);

это распечатывает 21;

int a='\100';
System.out.println(a);

это распечатывает 64.

VAr
источник
22
Похоже, он интерпретирует число как восьмеричное.
Nikhil
5
int a='\15'сначала создает charвосьмеричное число «15» (десятичное 13, как char, это ascii «Возврат каретки»), которое затем преобразовывается в intцелое число. Это законно, поскольку символы представляют собой 16-битные целые числа, поэтому это безопасное преобразование, и Java не выдает никаких уведомлений о преобразовании. Другие ответы уже охватывают все восьмеричные / десятичные числа.
Майк 'Pomax' Камерманс, 01 окт.13,

Ответы:

116

Вы назначили символьный литерал, который разделен одинарными кавычками, например 'a'(в отличие от строкового литерала, который, например, разделен двойными кавычками "a") intпеременной. Java выполняет автоматическое расширение приведения от 16-битного беззнакового charк 32-битному подписанному int.

Однако, когда символьный литерал представляет собой обратную косую черту, за которой следуют 1-3 цифры, это восьмеричное ( основание / основание 8) представление символа. Таким образом:

  • \15= 1 × 8 + 5 = 13 (возврат каретки; то же, что '\r')
  • \25 = 2 × 8 + 5 = 21 (символ NAK - отрицательное подтверждение)
  • \100= 1 × 64 + 0 × 8 + 0 = 64 (символ @; то же, что '@')

Для получения дополнительной информации о символьных литералах и escape-последовательностях см. Разделы JLS:

Цитата BNF из 3.10.6:

OctalEscape:
    \ OctalDigit
    \ OctalDigit OctalDigit
    \ ZeroToThree OctalDigit OctalDigit

OctalDigit: one of
    0 1 2 3 4 5 6 7

ZeroToThree: one of
    0 1 2 3
Богемный
источник
3
Я не могу найти его в разделе 3.10.1 .. Это в 3.10.4, Символьные литералы
Рафи Камаль
1
Раздел о целочисленных литералах не имеет значения. См. Раздел 3.10.4 . Также см. Раздел 3.10.6 относительно управляющих последовательностей символов и строк.
Тед Хопп
1-3 digits- так должно было быть 0-3. И это для трехзначного восьмеричного, двухзначного восьмеричного числа все еще может быть от 0-7. напр. '\ 77' по-прежнему действителен.
Джаямохан 01
6
@Jayamohan Я имел в виду 1-3 по количеству, а не по стоимости
Bohemian
@ Богемный. Хороший ответ. Я предлагаю вам добавить сюда синтаксис восьмеричного escape-литерала, чтобы он был более понятным. :)
Рохит Джайн
19

Обозначение \nnnобозначает восьмеричный символьный код в Java. so int a = '\15'назначает автоматически преобразованное значение восьмеричного символа 15, aкоторому является десятичное 13.

Бахман Мовакар
источник
5
Обозначения \nnnвовсе не означает восьмеричное число в Java. В коде OP он обозначает escape-последовательность восьмеричных символов. Окружающие кавычки важны. Затем символ расширяется до целочисленного значения с помощью присваивания. (Восьмеричные числа обозначаются ведущей нулевой цифрой.)
Тед Хопп
Хорошая точка зрения; должен был упомянуть авто-кастинг в ответе. Обновил ответ.
Bahman Movaqar 01
6

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

Нихил
источник