JavaRush /Blog Java /Random-PL /Rzutowanie (konwersja) typów pierwotnych w Javie

Rzutowanie (konwersja) typów pierwotnych w Javie

Opublikowano w grupie Random-PL
Cześć! Przeglądając JavaRush, natrafiłeś na typy pierwotne więcej niż raz. Oto krótka lista tego, co o nich wiemy:
  1. Nie są one obiektami i reprezentują wartość przechowywaną w pamięci
  2. Istnieje kilka typów typów pierwotnych:
    • Wszystkie liczby - byte, short, int,long
    • Liczby zmiennoprzecinkowe (ułamkowe) - floatidouble
    • Wartość logiczna -boolean
    • Symboliczne (do wskazania liter i cyfr) -char
  3. Każdy z nich ma swój własny zakres wartości:
Typ prymitywny Rozmiar w pamięci Zakres wartości
bajt 8 bitowy -128 do 127
krótki 16-bitowy do -32768 do 32767
zwęglać 16-bitowy od 0 do 65536
wew 32 bity od -2147483648 do 2147483647
długi 64 bity od -9223372036854775808 do 9223372036854775807
platforma 32 bity od (2 do potęgi -149) do ((2-2 do potęgi -23)*2 do potęgi 127)
podwójnie 64 bity od (-2 do potęgi 63) do ((2 do potęgi 63) - 1)
wartość logiczna 8 (w przypadku użycia w tablicach), 32 (w przypadku użycia w przypadku innych niż tablice) prawda czy fałsz
Ale oprócz wartości typy różnią się także rozmiarem pamięci. intzajmuje więcej niż byte. A long– więcej niż short. Ilość pamięci zajmowanej przez prymitywy można porównać do lalek gniazdujących: Rozszerzanie i kurczenie typów pierwotnych - 2 Wewnątrz lalki gniazdującej jest wolne miejsce. Im większa lalka do gniazdowania, tym więcej miejsca. longMniejszą z łatwością zmieścimy w dużej lalce lęgowej int. Pasuje łatwo i nie musisz robić nic więcej. W Javie podczas pracy z elementami podstawowymi nazywa się to konwersją automatyczną. W inny sposób nazywa się to rozszerzeniem. Oto prosty przykład rozszerzenia:
public class Main {

   public static void main(String[] args) {

       int bigNumber = 10000000;

       byte littleNumber = 16;

       bigNumber = littleNumber;
       System.out.println(bigNumber);
   }
}
Tutaj przypisujemy wartość bytezmiennej int. Przypisanie przebiegło pomyślnie i bez żadnych problemów: wartość przechowywana w bytezajmuje mniej miejsca w pamięci, niż „mieści się” w int. „Mała laleczka gniazdująca” (wartość byte) z łatwością mieści się w „dużej matrioszce” (zmienna int). Co innego, jeśli spróbujesz zrobić odwrotnie – wstaw dużą wartość do zmiennej, która nie jest zaprojektowana dla takich rozmiarów. Zasadniczo ta sztuczka nie zadziała z prawdziwymi lalkami gniazdującymi, ale w Javie będzie działać, ale z niuansami. Spróbujmy umieścić wartość intw zmiennej short:
public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = bigNumber;//błąd!
   System.out.println(bigNumber);
}
Błąd! Kompilator rozumie, że próbujesz zrobić coś niestandardowego i umieszcza dużą lalkę matrioszki ( int) w małej ( short). Błąd kompilacji w tym przypadku jest ostrzeżeniem kompilatora: „ Hej, czy na pewno chcesz to zrobić? „Jeśli jesteś pewien, powiedz o tym kompilatorowi: „ Wszystko jest w porządku, wiem, co robię!” Ten proces nazywa się jawną konwersją typu lub zawężaniem . Aby dokonać zawężenia, musisz wyraźnie wskazać typ, na który chcesz rzutować swoją wartość. Innymi słowy, odpowiedz na pytanie kompilatora: „ No cóż, w której z tych małych lalek chcesz umieścić tę dużą lalkę?” W naszym przypadku będzie to wyglądać następująco:
public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = (short) bigNumber;
   System.out.println(littleNumber);
}
Wyraźnie wskazaliśmy, że chcemy dopasować wartość intdo zmiennej shorti wziąć za to odpowiedzialność. Kompilator, widząc wyraźne wskazanie węższego typu, wykonuje konwersję. Jaki będzie wynik? Dane wyjściowe konsoli: -27008 Trochę nieoczekiwane. Dlaczego właśnie tak? To właściwie proste. Pierwotnie mieliśmy wartość - 10000000. Została ona zapisana w zmiennej int, która zajmowała 32 bity, a w formie binarnej wyglądała tak: Rozszerzanie i kurczenie typów pierwotnych - 3 Zapisujemy tę wartość do zmiennej short, ale może ona przechowywać tylko 16 bitów! W związku z tym zostanie tam przeniesionych tylko pierwszych 16 bitów naszego numeru, reszta zostanie odrzucona. W rezultacie zmienna shortbędzie zawierać wartość Rozszerzanie i kurczenie typów pierwotnych - 4, która w postaci dziesiętnej jest dokładnie równa -27008. Dlatego kompilator „poprosił o potwierdzenie” w postaci jawnego rzutowania na konkretny typ. Po pierwsze, pokazuje, że bierzesz odpowiedzialność za wynik, a po drugie, mówi kompilatorowi, ile miejsca przydzielić podczas rzutowania typów. Przecież gdybyśmy w ostatnim przykładzie rzutowali intna type byte, a nie na short, mielibyśmy do dyspozycji tylko 8 bitów, a nie 16, i wynik byłby inny. W przypadku typów ułamkowych ( floati double) zwężanie przebiega inaczej. Jeśli spróbujesz zamienić taką liczbę na liczbę całkowitą, jej część ułamkowa zostanie odrzucona.
public static void main(String[] args) {

   double d = 2.7;

   long x = (int) d;
   System.out.println(x);
}
Wyjście konsoli: 2

Typ danych char

Wiesz już, że typ char służy do wyświetlania pojedynczych znaków.
public static void main(String[] args) {

   char c = '!';
   char z = 'z';
   char i = '8';

}
Ale ma wiele funkcji, które należy zrozumieć. Spójrzmy jeszcze raz na tabelę z zakresami wartości:
Typ prymitywny Rozmiar w pamięci Zakres wartości
bajt 8 bitowy -128 do 127
krótki 16-bitowy -32768 do 32767
zwęglać 16-bitowy od 0 do 65536
wew 32 bity od -2147483648 do 2147483647
długi 64 bity od -9223372036854775808 do 9223372036854775807
platforma 32 bity od (2 do potęgi -149) do ((2-2 do potęgi -23)*2 do potęgi 127)
podwójnie 64 bity od (-2 do potęgi 63) do ((2 do potęgi 63)-1)
wartość logiczna 8 (w przypadku użycia w tablicach), 32 (w przypadku użycia w przypadku innych niż tablice) prawda czy fałsz
Typ charma zakres liczbowy od 0 do 65536. Ale co to oznacza? W końcu charsą to nie tylko cyfry, ale także litery, znaki interpunkcyjne... Faktem jest, że wartości charsą przechowywane w Javie w formacie Unicode. Z Unicode zetknęliśmy się już w jednym z poprzednich wykładów. Prawdopodobnie pamiętasz, że Unicode to standard kodowania znaków, który obejmuje znaki z prawie wszystkich pisanych języków świata. Innymi słowy, jest to lista kodów specjalnych, w której znajduje się kod dla prawie dowolnego znaku z dowolnego języka. Ogólna tabela Unicode jest bardzo duża i oczywiście nie trzeba się jej uczyć na pamięć. Oto na przykład fragment: Rozszerzanie i kurczenie typów pierwotnych - 5 Najważniejsze jest, aby zrozumieć zasadę przechowywania wartości chari pamiętać, że znając kod konkretnego symbolu, zawsze możesz go uzyskać w programie. Spróbujmy tego z jakąś losową liczbą:
public static void main(String[] args) {

   int x = 32816;

   char c = (char) x ;
   System.out.println(c);
}
Dane wyjściowe konsoli: 耰 To jest format, w jakim znaki są przechowywane w Javie char. Każdy znak odpowiada liczbie - kodowi numerycznemu składającemu się z 16 bitów lub dwóch bajtów. Unicode 32816 odpowiada znakowi 耰. Zwróć uwagę na ten moment. W tym przykładzie użyliśmy zmiennej int. Zajmuje 32 bity pamięci , natomiast char16 . Tutaj wybraliśmy , ponieważ potrzebny nam numer 32816 jest poza zakresem . Chociaż rozmiar , podobnie jak krótki, wynosi 16 bitów, w zakresie nie ma liczb ujemnych, więc zakres „dodatni” jest dwukrotnie większy (65536 zamiast 32767 ). Możemy użyć , o ile nasz kod mieści się w zakresie 65536. Ale jeśli utworzymy liczbę , zajmie ona więcej niż 16 bitów. A zawężając typy: intshortcharcharcharshortintint >65536
char c = (char) x;
dodatkowe bity zostaną odrzucone, a wynik będzie zupełnie nieoczekiwany.

Funkcje dodawania znaków char i liczb całkowitych

Spójrzmy na ten niezwykły przykład:
public class Main {

   public static void main(String[] args) {

      char c = '1';

      int i = 1;

       System.out.println(i+c);
   }
}
Wyjście konsoli: 50 O_O Gdzie jest logika? 1+1, skąd się wzięło 50?! Wiesz już, że wartości charprzechowywane są w pamięci jako liczby z zakresu od 0 do 65536, reprezentujące Unicode naszej postaci. Rozszerzanie i kurczenie typów pierwotnych - 6 Więc oto jest. Kiedy wykonujemy dodawanie, chara jakiś typ liczby całkowitej charjest konwertowany na liczbę, która mu odpowiada w Unicode. Kiedy w naszym kodzie dodaliśmy 1 i 1, symbol 1 został przekształcony w jego kod, który wynosi 49 (możesz to sprawdzić w tabeli powyżej). Zatem wynik wyniósł 50. Weźmy jeszcze raz naszego starego znajomego za przykład i spróbujmy go dodać z jakąś liczbą.
public static void main(String[] args) {

   char c = '耰';
   int x = 200;

   System.out.println(c + x);
}
Wyjście z konsoli: 33016 Już dowiedzieliśmy się, że odpowiada kodowi 32816. A gdy dodamy tę liczbę do 200, otrzymamy dokładnie nasz wynik - 33016 :) Mechanizm działania, jak widać, jest dość prosty.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION