Jaka jest semantyka języka Java w przypadku liczby ze zmianą znaczenia w literale znakowym, np. „\ 15”?


85

Proszę wyjaśnić, co dokładnie dzieje się, gdy wykonywane są następujące sekcje kodu:

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

to wypisuje 13;

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

to wypisuje 21;

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

to wypisuje 64.


22
Wygląda na to, że interpretuje liczbę jako ósemkową.
— Nikhil

5
int a='\15'najpierw tworzy na charpodstawie liczby ósemkowej „15” (13 dziesiętnie, jako znak, jest to ascii „Powrót karetki”), którą następnie przekształcasz na intliczbę całkowitą. Jest to legalne, ponieważ znaki są 16-bitowymi liczbami całkowitymi, więc jest to bezpieczna aktualizacja i Java nie wydaje żadnych powiadomień o przesyłaniu. Inne odpowiedzi obejmują już całą rzecz ósemkową / dziesiętną.
— Mike 'Pomax' Kamermans

Odpowiedzi:


116

Przypisałeś literał znakowy, który jest oddzielony pojedynczymi cudzysłowami, np. 'a'(W odróżnieniu od literału String, który jest oddzielony podwójnymi cudzysłowami, np. "a") Do intzmiennej. Java automatycznie poszerza rzutowanie z 16-bitowego bez znaku chardo 32-bitowego ze znakiem int.

Jednak gdy literał znakowy jest odwrotnym ukośnikiem, po którym następują 1-3 cyfry, jest to ósemkowa ( podstawa / podstawa 8) reprezentacja znaku. A zatem:

  • \15= 1 × 8 + 5 = 13 (powrót karetki; tak samo jak '\r')
  • \25 = 2 × 8 + 5 = 21 (znak NAK - negatywne potwierdzenie)
  • \100= 1 × 64 + 0 × 8 + 0 = 64 (symbol @; to samo co '@')

Aby uzyskać więcej informacji na temat literałów znaków i sekwencji ucieczki, zobacz sekcje JLS:

Cytując BNF z 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
Nie mogę go znaleźć w sekcji 3.10.1. Jest w 3.10.4, Literały postaci
— Rafi Kamal

1
Sekcja poświęcona literałom całkowitym jest nieistotna. Patrz sekcja 3.10.4 . Zobacz także sekcję 3.10.6, aby poznać sekwencje specjalne znaków i łańcuchów.
— Ted Hopp

1-3 digits- powinno być 0-3. A jeśli chodzi o 3-cyfrowy ósemkowy, dwucyfrowy ósemkowy nadal może mieć od 0-7. dawny. „\ 77” jest nadal ważny.
— Jayamohan

6
@Jayamohan Miałem na myśli 1-3 pod względem ilości, a nie wartości
— Bohemian

@Czech. Niezła odpowiedź. Proponuję dodać tutaj składnię ósemkowego literału ucieczki, aby była bardziej przejrzysta. :)
— Rohit Jain

19

Notacja \nnnoznacza ósemkowy kod znaku w Javie. więc int a = '\15'przypisuje automatycznie rzucaną wartość znaku ósemkowego 15, do aktórego jest dziesiętnie 13.


5
Zapis \nnnma nie oznaczają liczbę ósemkową w Javie. W kodzie OP oznacza ósemkową sekwencję ucieczki znaków. Otaczające cudzysłowy są niezbędne. Znak jest następnie rozszerzany do wartości całkowitej przez przypisanie. (Liczby ósemkowe są oznaczone początkową cyfrą zerową).
— Ted Hopp

Słuszna uwaga; Powinienem wspomnieć o automatycznej obsadzie w odpowiedzi. Zaktualizowałem odpowiedź.
— Bahman Movaqar

6

Fakt, że cyfry umieściłeś w cudzysłowie, każe podejrzewać, że interpretuje to liczbę jako literał znakowy. Kolejne cyfry muszą być zapisane ósemkowo.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.