2015-06-12 36 views
14

Dlaczego następujący kod nie generuje błąd?Dlaczego mogę generować char powyżej maksymalnej wartości?

System.out.println((char) 2147483647); 

Według oracle datatypes maksymalny rozmiar dla char jest 65,535.

  • char: Typ danych char jest jeden 16-bitowy znak Unicode. Ma minimalną wartość "\ u0000" (lub 0) i maksymalną wartość "\ uffff" (lub 65 535 włącznie).
+4

Co to jest drukowane? Nie "2147483647". Dlaczego nie? Jest twoja odpowiedź ... –

+0

Powoduje konwersję zawężającą, 2147483647 to int, a zwężasz ją, by była char. Jak już wspomniałeś, maksymalna wartość char to 65535. Jeśli wykonasz a, System.out.println ((int) (char) 2147483647); , zobaczysz, że wydrukuje 65535, a nie 2147483647. HTH –

Odpowiedz

26

Dlaczego mogę wygenerować char poza wartości max?

2147483647 nie jest char ale int.

Nie jesteś przypisując nieprawidłową wartość do char, jesteś odlewania ważnego int do char a następnie Zawężenie Primitive Konwersja zastosowania zasady. Zobacz Java specs: §5.1.3.

W skrócie zachowujesz najniższe 16 bitów oryginalnej liczby całkowitej ("Zwężająca się konwersja liczby całkowitej ze znakiem do typu całkowitego T po prostu odrzuca wszystkie oprócz n bitów najniższego rzędu, gdzie n to liczba bitów używanych do reprezentowania typu T. ").

Dlaczego poniższy kod nie generuje błędu?

Ponieważ nie jest to błąd, jest to dobrze zdefiniowane zachowanie.

+1

"Int", a nie "Integer"? – immibis

+0

@immibis nie jest 'Integer', an' int'! ;) Tak dziękuję. Pochodzenie było _integer_. –

-1

Właściwie odpowiedź na Twoje pytanie jest nie można.

Dlaczego nie widzisz żadnego błędu?
Ponieważ Character.MAX_VALUE + 1 = Character.MIN_VALUE ... same jak Integer.MAX_VALUE i innych, JVM traktuje ją jako pętlę, aby uniknąć tego rodzaju problemów ... ale daje fałszywe wyniki podczas próby obliczyć ....

Sprawdź this question dalszego i informacje techniczne

+0

Przepełnienie? Nie ... 16 bitów MSB jest po prostu odrzucanych. –

+1

@AdrianoRepetti Piszę pytanie połączone .. ale jak to rozumiem, mogę * wypróbować * przepełnienie ... ale tak się nie stanie ... –

+0

Podczas przesyłania nie ma przepełnienia. Najważniejsze dane są po prostu tracone. Zachowuje się tak samo, jak starsze języki, takie jak C++. Rzucenie prymitywów jest sposobem, w jaki programista mówi: "Tak, wiem, że stracę dane i zaakceptuję tę konsekwencję". W związku z tym programiści powinni unikać przesyłania, chyba że * potrzebują *, ponieważ kompilator chroni cię przed robieniem głupich rzeczy przez przypadek. – sfdcfox

0

Działa to z dowolnym typem danych, nazywa się to integer overflow, a podczas rzucania dowolnych bitów poza rozmiarami typu, który jest rzutowany, jest obcięte.

+0

Połowa. Tak, bajty są usuwane. Nie, nic wspólnego z przepełnieniem. –

6

zrobić konwersję zwężenie z int do char, który jest dozwolony see java spec: 5.1.3. Narrowing Primitive Conversion:

Konwersja zwężenie liczba całkowita ze znakiem do integralnego rodzaju T prostu odrzuca wszystko ale n najniższych bitów rzędu, gdzie n jest liczba bitów używanych do reprezentowania typu T. Oprócz możliwej utraty informacji o wielkości wartości liczbowej może to spowodować, że znak uzyskanej wartości będzie różnił się od znaku wartości wejściowej.

Powstały char nie jest większy niż Character.MAX_VALUE. Kompilator konwertuje (char) 2147483647 do 65535

3

char to 16-bitowy typ danych, do którego można przesyłać wartości numeryczne.

Gdy oddajesz 32-bitową liczbę całkowitą do 16-bitowego krótkiego (lub char), tracisz górne bity źródła.

Int32 i = 2147483647; // 0x7FFFFFFF 
Int16 s = (Int16) i; //  0xFFFF (65535) 
char c = (char) i; //  0xFFFF (65535)