Qual é a semântica Java de um número de escape em um literal de caractere, por exemplo, '\ 15'?

85

Explique o que, exatamente, acontece quando as seguintes seções de código são executadas:

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

isso imprime 13;

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

isso imprime 21;

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

isso imprime 64.

VAr
fonte
22
Parece que ele está interpretando o número como um octal.
Nikhil
5
int a='\15'primeiro cria um charbaseado no número octal "15" (decimal 13, como um caractere, é o "Retorno de carro" ascii), que você então converte para um intinteiro. Isso é legal, já que chars são inteiros de 16 bits, portanto, é um upcast seguro e nenhum aviso sobre a conversão é emitido pelo Java. As outras respostas já cobrem toda a coisa octal / decimal.
Mike 'Pomax' Kamermans
3
possível duplicata de Por que '\ 117' é um literal de caractere válido em Java?
gparyani 01 de

Respostas:

116

Você atribuiu um literal de caractere, que é delimitado por aspas simples, por exemplo 'a'(diferente de um literal String, que é delimitado por aspas duplas, por exemplo "a") a uma intvariável. Java faz uma conversão de ampliação automática do não assinado de 16 bits charpara o assinado de 32 bits int.

No entanto, quando um literal de caractere é uma barra invertida seguida por 1-3 dígitos, é uma representação octal ( base / raiz 8) do caractere. Portanto:

  • \15= 1 × 8 + 5 = 13 (um retorno de carro; o mesmo que '\r')
  • \25 = 2 × 8 + 5 = 21 (um caractere NAK - confirmação negativa)
  • \100= 1 × 64 + 0 × 8 + 0 = 64 (o símbolo @; o mesmo que '@')

Para obter mais informações sobre literais de caracteres e sequências de escape, consulte as seções JLS:

Citando o BNF de 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
Boêmio
fonte
3
Não consigo encontrar na seção 3.10.1 .. Está em 3.10.4, Literais de caracteres
Rafi Kamal
1
A seção sobre literais inteiros é irrelevante. Consulte a Seção 3.10.4 . Veja também a Seção 3.10.6 para sequências de escape de caracteres e strings.
Ted Hopp de
1-3 digits- deveria ter sido 0-3. E é para octal de 3 dígitos, octal de dois dígitos ainda pode ter de 0-7. ex. '\ 77' ainda é válido.
Jayamohan
6
@Jayamohan eu quis dizer 1-3 em quantidade, não em valor
Boêmio
@Boêmio. Boa resposta. Eu sugiro que você adicione a sintaxe do literal de escape octal aqui, então ficará mais claro. :)
Rohit Jain
19

A notação \nnndenota um código de caractere octal em Java. então int a = '\15'atribui o valor convertido automaticamente do caractere octal 15, ao aqual é o decimal 13.

Bahman Movaqar
fonte
5
A notação \nnné que não denotar um número octal em Java. No código do OP, ele denota uma seqüência de escape de caractere octal. As aspas ao redor são essenciais. O caractere é então ampliado para um valor inteiro pela atribuição. (Os números octais são denotados por um dígito zero à esquerda.)
Ted Hopp de
Bom ponto; deveria ter mencionado o elenco automático na resposta. Atualizou a resposta.
Bahman Movaqar
6

O fato de você colocar os dígitos entre aspas me faz suspeitar que ele está interpretando o número como um literal de caractere. Os dígitos a seguir devem estar em octal.

Nikhil
fonte