1. Odlewanie

Rzutowanie typów w Javie

Zmienne typów pierwotnych (z wyjątkiem typu boolean) służą do przechowywania różnych typów liczb. I chociaż typy zmiennych są zawsze niezmienne, istnieje miejsce, w którym można przeprowadzić konwersję typów. A to miejsce to zadanie .

Możesz przypisywać sobie zmienne różnych typów. W takim przypadku wartość pobrana ze zmiennej jednego typu zostanie przekonwertowana na wartość innego typu i przypisana do drugiej zmiennej. W związku z tym można wyróżnić dwa rodzaje konwersji typów: rozszerzanie i zawężanie.

Rozbudowa typu jest jak przesiadka z małego koszyczka do dużego – operacja jest niezauważalna i bezbolesna. Zawężanie czcionek to przerzucanie się z dużego kosza do małego: może zabraknąć miejsca i coś trzeba będzie wyrzucić.

Oto typy posortowane według rozmiaru koszyka:

Rzutowanie typów w Javie 2


2. Rozszerzenie typu

Często konieczne jest przypisanie zmiennej jednego typu liczbowego do zmiennej innego typu liczbowego. Jak to zrobić?

W Javie istnieją 4 typy liczb całkowitych:

Typ Rozmiar
byte 1 bajt
short 2 bajtа
int 4 bajtа
long 8 bajt

Większą zmienną zawsze można przypisać do mniejszych zmiennych.

Zmienną typu longmożna łatwo przypisać do zmiennych typu inti short. byteZmienną typu intmożna przypisać do zmiennych typu shorti byte. Cóż, zmienne typu shortmożna przypisać do zmiennych typu byte.

Przykłady:

Kod Opis
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
Ten kod skompiluje się dobrze.

Taka konwersja z mniejszego typu na większy nazywana jest rozszerzeniem typu .

A co z liczbami rzeczywistymi?

Z nimi wszystko jest takie samo - rozmiar ma znaczenie:

Typ Rozmiar
float 4 bajtа
double 8 bajt

Zmienną typu doublemożna łatwo przypisać do zmiennej typu float. A tutaj z typami całkowitymi jest bardziej interesująco.

Zmienną typu floatmożna przypisać do zmiennej dowolnego typu całkowitego. Nawet typ long, który ma długość 8 bajtów. A zmiennej typu doublemożna w ogóle przypisać cokolwiek: zmienną dowolnego typu całkowitego i zmienną typu float:

Kod Notatka
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

Należy pamiętać, że rzutowanie na typ rzeczywisty może spowodować utratę precyzji z powodu braku cyfr znaczących.

Podczas konwersji z liczb całkowitych na ułamki, najmniejsze części liczby mogą zostać odrzucone. Lecz odkąd celem liczby ułamkowej jest przechowywanie przybliżonej wartości, takie przypisanie jest dozwolone.


3. Wpisz zawężenie

A co z innymi opcjami? Co zrobić, jeśli musisz intprzypisać wartość zmiennej typu do zmiennej typu long?

Wyobraź sobie, że zmienną jest koszyk. Posiadamy kubełki o różnej wielkości: 1, 2, 4 i 8 bajtów. Podczas przenoszenia ciast z mniejszego kosza do dużego nie będzie żadnych problemów. Ale przechodząc z większej części ciasta na mniejszą, można ją zgubić.

Ta konwersja z większego typu na mniejszy jest nazywana zawężeniem typu . Przy takim przypisaniu część liczby może po prostu nie pasować do nowej zmiennej i „zostać w tyle”.

Zawężając typ, musimy wyraźnie pokazać kompilatorowi, że nie popełniliśmy błędu, a odrzucenie części numeru zostało wykonane świadomie. W tym celu używany jest operator rzutowania typów. To jest nazwa typu w nawiasach .

W takich sytuacjach kompilator Javy wymaga od programisty dostarczenia operatora konwersji typu. Ogólnie wygląda to tak:

(тип) wyrażenie

Przykłady:

Kod Opis
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
Za każdym razem musisz jawnie określić operator konwersji typu

W tym przypadku ajest równy 1i wydaje się zbędny. A gdyby abyło ich więcej?

Kod Opis
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

Milion pasuje idealnie zarówno w typie, longjak i typie int. Ale przy przypisywaniu miliona do zmiennej typu shortpierwsze dwa bajty zostały odrzucone i pozostały tylko dwa ostatnie. A przy przypisywaniu do typu bytezwykle pozostawał jeden ostatni bajt.

Urządzenie liczb w pamięci:

Typ Notacja binarna Notacja dziesiętna
int 0b 00000000 00001111 01000010 01000000 1,000,000
short 0b 01000010 01000000 16,960
byte 0b 01000000 64

Typchar

Type char, podobnie jak type short, zajmuje dwa bajty, ale zawsze musisz użyć operatora rzutowania, aby przekonwertować je na siebie. Chodzi o to, że typ shortjest podpisany i może zawierać wartości od -32,768do +32,767, a typ charjest niepodpisany i może zawierać wartości od 0do 65,535.

charNie można przechowywać liczb ujemnych, które można przechowywać w short. I shortnie możesz przechowywać liczb większych niż 32,767, które można przechowywać w char.


4. Typ wyrażenia

Ale co, jeśli to samo wyrażenie używa zmiennych różnych typów? Logiczną odpowiedzią jest to, że należy je najpierw przekonwertować na wspólny typ. Ale co?

Oczywiście więcej.

Java zawsze konwertuje na większy typ. Z grubsza mówiąc, najpierw rozszerzany jest typ jednego z uczestników operacji, a dopiero potem operacja o wartości tego samego typu.

Jeśli typy inti biorą udział w wyrażeniu long, wartość typu intzostanie przekonwertowana na typ longi dopiero wtedy weźmie udział w operacji:

Kod Opis
int a = 1;
long b = 2;
long c = a + b;
azostanie rozwinięty do typu longi dopiero wtedy nastąpi dodanie.

Liczb zmiennoprzecinkowych

Jeśli wyrażenie zawiera liczbę całkowitą i liczbę zmiennoprzecinkową ( float/ ), przed wykonaniem operacji doubleliczba całkowita zostanie przekonwertowana na liczbę zmiennoprzecinkową ( float/ ).double

Jeśli operacja obejmuje floati double, to floatzostanie przekonwertowana na double. Czego właściwie można się spodziewać.

Niespodzianka

Typy byte, short, charsą zawsze konwertowane na typ intpodczas interakcji ze sobą. Nic dziwnego, że typ intjest uważany za standardowy typ całkowity.

Mnożenie przez bytebędzie short. intMnożenie przez bytebędzie byte. intNawet jeśli dodasz bytei byte, to będzie int.

Jest tego kilka powodów. Przykłady:

Kod Opis
byte a = 110;
byte b = 120;
byte c = a * b;   // ошибка
110 * 120will be 13,200, która jest nieco większa niż maksymalna wartość typu byte:127
byte a = 110;
byte b = 120;
byte c = a + b;   // ошибка
110 + 120will be 230, która jest również nieco większa niż maksymalna wartość typu byte:127

Ogólnie rzecz biorąc, mnożąc liczbę o długości 8 bitów (1 bajt) przez liczbę o długości 8 bitów (1 bajt), otrzymujemy liczbę o długości 16 bitów (2 bajty)

W związku z tym wszystkie operacje na typach całkowitych mniejszych niż intzawsze są natychmiast konwertowane na type int. A zatem, jeśli chcesz zapisać wynik obliczenia w zmiennej typu mniejszej niż int, zawsze będziesz musiał jawnie określić operację konwersji typu.

Przykłady:

Kod Opis
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
wyrażenie byte * bytebędzie typuint
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
wyrażenie byte + bytebędzie typuint
byte a = 1;
byte b = (byte) (a + 1);
wyrażenie byte + intbędzie typu int
jeden, który jest literałem type int.

5. Ważny niuans

Operacja rzutowania ma dość wysoki priorytet.

Dlatego jeśli wyrażenie zawiera, powiedzmy, operację dodawania i rzutowania typu, zostanie ona wykonana przed dodaniem.

Przykład:

Kod Opis
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
Operator rzutowania zostanie zastosowany tylko do zmiennej, aktóra ma już typ byte. Kod się nie skompiluje.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
Zgadza się.

Jeśli chcesz przekonwertować całe wyrażenie na określony typ, a nie tylko jeden z jego elementów, zawiń całe wyrażenie w nawiasy i umieść przed nimi operator rzutowania typu.