Kako postaviti pametne telefone i računala. Informativni portal

Java pretvara dvostruko u int. Primjer

Svaki izraz u Javi ima tip, koji je određen strukturom izraza i tipovima njegovih sastavnih operanda (konstante, varijable i metode). Međutim, ponekad ćemo možda morati eksplicitno pretvoriti izraz u drugi tip. Osim toga, u nekim situacijama, samo Java runtime obavlja takve konverzije implicitno.

Pretvorba vrsta T 1 do tipa T 2 dopušta da se izraz tipa T 1 u vrijeme prevođenja tretira kao izraz tipa T 2. U nekim slučajevima, ovo je čisto sintaktička konstrukcija koja ne utječe na generirani kod; u drugima, pretvorba tipa zahtijeva dodatne radnje u vremenu izvođenja za promjenu vrijednosti izraza ili dodatne provjere ispravnosti primijenjene konverzije. primjeri:

  • Pretvorba vrsta int u vrsti dugo zahtijeva 32-bitni cijeli broj za proširenje na 64-bitni cijeli broj tijekom izvođenja. U ovom slučaju nema gubitka informacija.
  • Pretvorba vrsta plutati u vrsti dugo zahtijeva netrivijalnu pretvorbu 32-bitne plutajuće vrijednosti u 64-bitni cijeli broj tijekom izvođenja. Gubitak informacija može ili ne mora doći, ovisno o izvornoj vrijednosti.
  • Pretvaranje iz niti u objekt je jednostavno: budući da je nit potomak objekta, svaka referenca na objekt tipa Thread automatski je referenca na objekt.
  • Pretvaranje iz objekta u nit zahtijeva provjeru vremena izvođenja. Ako je referenca koju treba pretvoriti doista referenca na objekt tipa Thread, tada se vraća kao rezultat pretvorbe, inače se stvara iznimka.

5.4.1.1. Proširivanje broja konverzija

Proširivanje broja konverzija- to su pretvorbe numeričkog tipa u "veći" brojčani tip, koji se smatraju sigurnima, jer ne dovode do gubitka vrijednosti pretvorene vrijednosti. Takve konverzije u Javi su:

  • transformacije bajt v kratak, int, dugo, plutati i dvostruko;
  • transformacije kratak v int, dugo, plutati i dvostruko;
  • transformacije čar v int, dugo, plutati i dvostruko;
  • transformacije int v dugo, plutati i dvostruko;
  • transformacije dugo v plutati i dvostruko;
  • transformacije plutati v dvostruko.

Zapravo, pretvaranje cjelobrojne vrijednosti u float vrijednost može dovesti do gubitka preciznosti, odnosno gubitka značajnih znamenki. Dakle, sljedeći primjer

Test klase (javni statički void main (String args) (int bigNumber = 1234567890; float approximate = bigNumber; System.out.println (približan);))

prikazat će niz 1234567936. To je zbog činjenice da prilikom pretvorbe int v plutati rezultirajuća vrijednost je 1,2345679E9 zbog činjenice da je mantisa brojeva poput plutati prihvaća samo 8 decimalnih znamenki (ovdje bi se pretvorba u vrstu trebala koristiti za ispravan rad dvostruko). Međutim, runtime sustav nikada ne generira pogreške prilikom izvođenja navedenih transformacija.

5.4.1.2. Sužavanje broja konverzija

Sužavanje broja konverzija- To su pretvorbe iz numeričke vrste u "manji" brojčani tip, što može dovesti do gubitka veličine i gubitka preciznosti. Takve konverzije u Javi su:

  • transformacije bajt v čar;
  • transformacije kratak v bajt i čar;
  • transformacije int v bajt, kratak i čar;
  • transformacije dugo v bajt, kratak, int i čar;
  • transformacije plutati v bajt, kratak, int, dugo i čar;
  • transformacije dvostruko v bajt, kratak, int, dugo, plutati i čar;

Ovdje nećemo detaljno razmatrati pravila po kojima se te transformacije odvijaju, budući da su intuitivno razumljiva, a formalno prilično glomazna. Kada ih koristite, važno je zapamtiti da Java, za razliku od drugih jezika, ne generira pogreške prekomjernog ili nižeg protoka, pa kontrola nad ispravnošću transformacija u potpunosti pada na programera.

5.4.1.3. Proširive transformacije veze

Proširive transformacije veze Jesu li konverzije izvedenih referentnih tipova u tipove njihovih predaka, koje ne zahtijevaju nikakvu radnju tijekom izvođenja i nikada ne generiraju pogreške. Takve konverzije u Javi su:

  • pretvaranje bilo koje klase ili sučelja u svog pretka (posebno u tip Object);
  • pretvaranje klase u sučelje koje implementira;
  • pretvaranje bilo kojeg niza u tip objekta ili tip koji se može klonirati;
  • pretvaranje niza tipa S u niz tipa T ako su S i T referentni tipovi i konverzija iz S u T se širi;
  • pretvaranje null tipa u bilo koji referentni tip.

5.4.1.4. Sužavanje konverzija veza

Sužavanje konverzija veza Jesu li pretvorbe iz izvedenih referentnih tipova u njihove tipove potomaka. Ove konverzije zahtijevaju provjeru njihove legitimnosti tijekom izvođenja i mogu izazvati ClassCastException. Takve konverzije u Javi su:

  • pretvaranje bilo koje klase u njezin potomak (posebno pretvaranje tipa Object u bilo koju drugu klasu);
  • pretvaranje klase u sučelje kada klasa nije konačna i ne implementira dano sučelje (posebno, pretvaranje tipa Object u bilo koje sučelje);
  • pretvaranje tipa objekta u bilo koji niz;
  • pretvaranje bilo kojeg sučelja u klasu koja nije konačna;
  • pretvaranje bilo kojeg sučelja u klasu koja je konačna i implementira ovo sučelje;
  • pretvaranje sučelja J u sučelje K, kada J nije potomak K, i ne postoji metoda deklarirana u J i K s istim potpisom, ali različitim tipovima rezultata;
  • pretvaranje niza tipa S u niz tipa T ako su S i T referentni tipovi i pretvorba iz S u T se sužava.

5.4.1.5. Pretvorbe u nizove

Bilo koji izraz u Javi, uključujući null, može se pretvoriti u String.

5.4.1.6. Nevažeće konverzije

Sljedeće pretvorbe tipova zabranjene su u Javi:

  • pretvaranje bilo kojeg referentnog tipa u bilo koji primitivni tip;
  • pretvaranje bilo kojeg primitivnog tipa u bilo koji referentni tip osim String;
  • pretvaranje nulte vrste u bilo koji primitivni tip;
  • pretvorbe u tip null ili tip boolean;
  • pretvorbe tipa boolean na bilo koju drugu vrstu osim tipa String;
  • pretvaranje jedne klase u drugu, ako nitko od njih nije predak druge (osim pretvaranja u tip String);
  • pretvaranje klase u sučelje ako je klasa konačna i ne implementira dano sučelje;
  • pretvaranje klase u niz ako se klasa razlikuje od Object;
  • pretvaranje sučelja u klasu koja je konačna i ne implementira dano sučelje (osim pretvaranja u tip String);
  • pretvaranje J sučelja u K sučelje, ako postoji metoda deklarirana u J i K s istim potpisom, ali različitim tipovima rezultata;
  • pretvaranje niza u klasu koja nije Object i String;
  • pretvaranje niza u sučelje koje nije Cloneable;
  • pretvaranje niza tipa S u niz tipa T ako je pretvaranje S u T zabranjeno

5.4.2. Transformacijski konteksti

5.4.2.1. Pretvorba na zadatku

Pretvorba na zadatku javlja se kada je vrijednost izraza dodijeljena varijabli. Ovo pretvara tip izraza u tip varijable. Prilikom dodjele, uvijek su moguće pretvorbe proširenih tipova (i brojčanih i referentnih). Sužavanje konverzije moguće je samo ako su ispunjeni sljedeći uvjeti:

  • varijabla je tipa bajt, kratak ili čar;
  • vrijednost izraza je konstanta tipa int koja spada u raspon mogućih vrijednosti varijable.

Na primjer, bajt operator x = 123; recimo, budući da je konstanta 123 (tipa int) leži u rasponu dopuštenih vrijednosti tipa bajt.

Ako se tip izraza ne može pretvoriti u tip varijable, prevodilac generira pogrešku. Inače, kažemo da je vrsta izraza kompatibilan zadatak s promjenjivim tipom. Dakle, sljedeći isječak

Kratki s = 123; char c = s; // generira grešku kompilacije

će generirati pogrešku jer vrste čar i kratak su nekompatibilni u dodjeli prema gornjim definicijama (prva je implementirana u 16-bitnim neoznačenim riječima, a druga - sa predznakom).

5.4.2.2. Pretvaranje argumenata metode

Pretvaranje argumenata metode javlja se kada se stvarne vrijednosti argumenata pretvore u tip parametara metode ili konstruktora kada se ona pozove. U ovom slučaju, proširene pretvorbe tipova (i brojčanih i referentnih) su uvijek moguće, a pretvorbe suženja nisu dopuštene. Razlozi potonje zabrane mogu se objasniti sljedećim primjerom:

Test klase (statički int m (bajt a, int b) (vrat a + b;) statički int m (kratki a, kratki b) (povrat a - b;) javni statički void main (String args) (System.out. println ( m (1, 2)); // generira pogrešku kompilacije))

Ovdje klasa Test sadrži dvije metode istog imena, koje se razlikuju samo po vrstama parametara. Ako su pretvorbe argumenata sužavanja dopuštene u Javi, vrijeme izvođenja moralo bi otkriti kojoj od ovih metoda pripada poziv m (1, 2). Kako bi izbjegli takve nejasnoće, programeri jezika radikalno su riješili problem: zabranili su takve pozive metoda. U ovoj situaciji, da bismo pozvali, na primjer, prvu metodu, moramo eksplicitno navesti tip prvog operanda (drugi već ima zadani tip int), naime m ((bajt) 1, 2).

5.4.2.3. Pretvaranje u niz

Pretvaranje u niz javlja se samo u jednom slučaju: kada se binarna + operacija primjenjuje na dva operanda, od kojih je jedan tipa String. U ovoj situaciji, drugi operand se također pretvara u tip String, a rezultat operacije je spajanje rezultirajućih nizova. Ovaj proces je detaljnije opisan u Ch. 5.14.

5.4.2.4. Eksplicitna konverzija tipa

Eksplicitna konverzija tipa javlja se kada se tip cast eksplicitno primjenjuje na operand. U ovoj situaciji mogu se primijeniti sve vrste pretvorbi tipova opisane iznad, osim pretvorbe u niz. Pokušaj eksplicitne pretvorbe u tip koji je gore označen kao zabranjen dovest će do pogreške kompilacije. Osim toga, ClassCastException može biti izbačen tijekom izvođenja ako je navedena konverzija nevažeća.

5.4.3. Pretvorbe tipa numeričkog operanda

Pretvorba tipova u procesu vrednovanja brojčanih izraza ima niz značajki. Oni se svode na dva slučaja: pretvaranje operanda u unarnim operacijama i u binarnim operacijama.

Prije izvođenja unarne operacije:

  • ako je operand tipa bajt, kratak ili čar, pretvara se u tip int;
  • u ostalim slučajevima, njegov tip se ne mijenja.

Prije izvođenja binarne operacije:

  • ako je jedan od operanada tipa dvostruko, tada se i drugi pretvara u tip dvostruko;
  • plutati, tada se i drugi pretvara u tip plutati;
  • inače, ako je jedan od operanada tipa dugo, tada se i drugi pretvara u tip dugo;
  • inače se oba operanda pretvaraju u tip int.

Ovo je prilično velika tema, ali pokušat ćemo je razmotriti što je moguće potpunije i istovremeno kompaktnije. Već smo djelomično dotaknuli ovu temu kada smo pogledali primitivne tipove Jave.

Pretvorbe između cjelobrojnih i vrijednosti s pomičnim zarezom moguće su u Javi. Osim toga, možete pretvoriti vrijednosti cijelog broja i vrijednosti s pomičnim zarezom u vrijednosti char i obrnuto, budući da svaki znak odgovara znamenki Unicode. Zapravo, boolean tip je jedini primitivni tip u Javi koji se ne može pretvoriti u drugi primitivni tip. Također, bilo koji drugi primitivni tip ne može se pretvoriti u boolean.

U Javi postoje dvije vrste konverzija: implicitno i eksplicitan.

Implicitna konverzija tipa izvodi se ako su ispunjeni sljedeći uvjeti:

  1. Obje vrste su kompatibilne
  2. Duljina ciljnog tipa veća je ili jednaka duljini vrste izvora

U svim ostalim slučajevima treba koristiti eksplicitna konverzija tipa.

Također postoje dvije vrste transformacija:

  1. Proširivanje konverzije
  2. Sužavanje konverzije

Transformacija proširenja ( proširenje konverzije) se događa kada se vrijednost istog tipa pretvori u širi tip sa širim rasponom valjanih vrijednosti. Java automatski izvodi pretvorbe proširenja, na primjer, ako dodijelite int literal double ili nepromijenjen char int. Implicitna konverzija je uvijek širi tip.

Ali ovdje može imati svoje male grablje. Na primjer, ako int vrijednost pretvorite u float vrijednost. A vrijednost int u binarnom prikazu ima više od 23 značajna bita, tada je moguć gubitak preciznosti, budući da tip float ima 23 bita dodijeljena za cijeli broj. Svi LSB-ovi int vrijednosti koje se ne uklapaju u 23 bita float mantise bit će odbačene, pa će se, iako je red brojeva sačuvati, izgubiti preciznost. Isto vrijedi i za pretvaranje long u double.

Proširivanje pretvorbe Java tipa također se može prikazati ovako:

Pune linije predstavljaju konverzije bez gubitka podataka. Isprekidane linije označavaju gubitak preciznosti tijekom pretvorbe.

Vrijedi malo objasniti zašto se npr. tip bajta ne pretvara automatski (ne eksplicitno) u tip char, iako je tip bajta širok 8 bita, a char 16, isto vrijedi i za pretvorbu kratkih ugljičiti se. To je zato što su byte i short potpisani tipovi podataka, dok je char nepotpisan. Stoga, u ovom slučaju, trebate koristiti eksplicitno uvođenje, budući da prevodilac treba eksplicitno naznačiti da znate što želite i kako će se predznačni bit bajtova i kratkih tipova obraditi prilikom pretvaranja u tip char.

U većini slučajeva, ponašanje char vrijednosti je isto kao i cjelobrojne vrijednosti; stoga se vrijednost char može koristiti gdje god su potrebne int ili long vrijednosti. Podsjetimo, međutim, da je char bez predznaka, pa se ponaša drugačije od kratkog, iako je raspon obje vrste 16 bita.

kratak s = ( kratak ) 0xffff; // Ovi bitovi predstavljaju broj -1
čar c = "\ uffff"; // Isti bitovi predstavljaju unicode znak
int i1 = s; // Pretvaranje kratkog u int daje -1
int i2 = c; // Pretvaranje char u int daje 65535

Transformacija sužavanja ( sužavanje konverzije) se događa kada se vrijednost pretvori u vrijednost tipa čiji raspon nije širi od izvornog. Pretvorbe sužavanja nisu uvijek sigurne: na primjer, pretvaranje cjelobrojne vrijednosti 13 u bajt ima smisla, ali pretvaranje 13000 u bajt nije mudro, budući da bajt može pohraniti samo brojeve od -128 do 127. Budući da se podaci mogu izgubiti tijekom sužavanja pretvorbu, Java prevodilac prigovara svakoj takvoj konverziji, čak i ako vrijednost koju treba pretvoriti spada u uži raspon navedene vrste:

int i = 13 ;
bajt b = i ; // Prevoditelj neće riješiti ovaj izraz

Jedina iznimka od ovog pravila je dodjela cjelobrojnog literala (int vrijednost) bajt varijabli ili kratkog ako literal odgovara rasponu varijable.

Pretvorbe suženja su uvijek eksplicitne pretvorbe..

Eksplicitna konverzija primitivnih tipova

Operator eksplicitne konverzije tipa ili, točnije, pretvorbe tipa su zagrade, unutar kojih je naznačen tip na koji se konverzija izvodi - (tip)... Na primjer:

int i = 13 ;
bajt b = ( bajt ) i ; // Prisilna konverzija int u bajt
i = ( int ) 13.456 ; // Prisilna konverzija literala tipa double u int 13

Najčešće se koristi lijevanje primitivnih tipova za pretvaranje vrijednosti s pomičnim zarezom u cijele brojeve... Pri čemu frakcijski dio vrijednosti s pomičnim zarezom jednostavno se odbacuje(to jest, vrijednost s pomičnim zarezom zaokružuje se prema nuli, a ne prema najbližem cijelom broju). U srži uzima se samo cijeli broj realnog tipa i već je bačen na ciljni cjelobrojni tip.

Prilikom donošenja prostranije cijeli tip na manje kapacitetne bitove visokog reda jednostavno se odbacuju... U biti, ovo je ekvivalentno operaciji modula vrijednosti koju treba izbaciti rasponom ciljnog tipa (na primjer, za tip bajta, to je 256).

Preveliki razlomak kada se pretvori u cijeli broj postaje MAX_VALUE ili MIN_VALUE.

Prevelik dvostruko kada se svede na plutati postaje Float.POSITIVE_INFINITY ili Float.NEGATIVE_INFINITY.

Tablica u nastavku je mreža u kojoj su, za svaki primitivni tip, naznačeni tipovi u koje se mogu pretvoriti i način pretvorbe. Pismo N u tablici znači nemogućnost pretvorbe. Pismo Y znači proširenje pretvorbe koje se obavlja automatski. Pismo S znači sužavanje konverzije koje zahtijeva eksplicitno djelovanje. Konačno, Y * znači automatsku pretvorbu proširenja, tijekom koje vrijednost može izgubiti neke od najmanje značajnih znamenki. To se može dogoditi prilikom pretvaranja int ili long u float ili double. Tipovi s pomičnim zarezom imaju širi raspon od cjelobrojnih tipova, tako da int ili long mogu biti predstavljeni kao float ili double. Međutim, tipovi s pomičnim zarezom su približni brojevi i ne moraju uvijek sadržavati toliko značajnih bitova u mantisi kao cjelobrojni tipovi.

Automatsko proširenje tipa u izrazima

Također je vrijedno spomenuti automatsku promociju (proširivanje) tipova u izrazima. S tim smo se već susreli kada smo razmatrali cjelobrojne tipove podataka i operacije nad njima, no ipak, ovdje je vrijedno podsjetiti kako bi se to još bolje savladalo i, štoviše, izravno povezano s ovom temom. U primjeru ispod, znak @ + , , * , / itd.

Odnosno, svi cjelobrojni literali u izrazima, kao i vrste bajt, kratak i čar proširiti na int ... Ako, kao što je gore opisano, nema drugih, većih tipova podataka ( dugo, plutati ili dvostruko). Stoga će gornji primjer izbaciti grešku kompilacije kao varijablu c je tipa bajt, a izraz b + 1, kao rezultat automatske promocije, ima tip int.

Implicitna prisila u izrazima zadatka

Iako se ovaj odjeljak odnosi na implicitnu pretvorbu (casting) tipova, ovdje smo dali njegovo objašnjenje, budući da u ovom slučaju funkcionira i automatsko proširenje tipova u izrazima, a zatim i implicitno pretvaranje tipova. Evo korpusa baleta. Mislim da će donji primjer sve razjasniti. Kao i u prethodnom objašnjenju, znak @ znači bilo koji valjani operator, na primjer + , , * , / itd.

Ovo vrijedi objasniti jednostavnim primjerom:

bajt b2 = 50 ;
b2 = b2 * 2 ; // neće kompajlirati
b2 *= 2 ; // će kompilirati, iako je ekvivalentno b2 = b2 * 2

Drugi red prikazan u primjeru neće se kompilirati zbog automatskog proširenja tipa u izrazima, budući da je izraz b2 * 2 tipa int, budući da dolazi do automatskog proširenja tipa (cijelobrojni literali u izrazu su uvijek int). Treći će red biti lak za kompajliranje, budući da će u njemu raditi implicitno uvođenje tipova u kombiniranom izrazu dodjele.

Boxing / Unboxing - pretvaranje primitivnih tipova u objekte omotača

Boks i unboxin su također prilično velike teme, ali su prilično jednostavne.

U srži boxing i unboxing primitivni su tipovi za i od wrapper objekata.

Za objekte omota primitivnih tipova vrijedi sve što je gore rečeno.

Klase omotača spomenute su u tablicama prilikom raščlanjivanja svakog od primitivnih tipova. Ali tada je to bilo samo spominjanje u tablici.

Dakle, za svaki primitivni tip postoji njegov stariji brat, i to uopće nije primitivan, već je prava klasa, s poljima i metodama. I za svaki takav par moguća je automatska konverzija.

Obično, ako program ima puno matematičkih izračuna, onda je bolje koristiti primitivne tipove, jer je brži i ekonomičniji u smislu resursa, ali ponekad je potrebno pretvoriti primitivni tip u objekt.

Dopustite mi da vam dam jednostavan primjer:

int i3 ;
bajt b2 = 3 ;
Bajt mojB ;
mojB= b2;
mojB++;
b2= mojB;
i3= mojB;

Ako još nije jasno zašto je to potrebno, onda to nije strašno, samo se vežite za uspomenu.

Prethodni govornik je prilično u potpunosti opisao transformaciju odozgo prema dolje, ali odozdo prema gore (po mom mišljenju) zahtijeva dodatna objašnjenja, jer je pitanje vrlo popularno i zanimljivo.

Kako radi eksplicitni casting

Vaš primjer pokazuje konverziju prema gore ( Upcasting):

List coll = novi ArrayList ();

Na ruski se prevodi na sljedeći način: stvori vranu, kao što je ptica. Napravite dinamički niz poput lista. U većini situacija konverzija prema gore potpuno je nepotrebna.
Međutim, casting funkcionira na intervjuima kada vam se postavljaju pitanja o nasljedstvu. Na primjer, web-mjesto quizful.net općenito sadrži mnoga pitanja o tipovima. Stoga ću objasniti značajke koje poznajem.

Dakle, u gornjem primjeru kreirali smo objekt tipa ArrayList i referencu tipa List. Zapamtite aksiome za ovu metodu:

1. Veza može upućivati ​​na bilo kojeg roditelja. Čak i jako davno. To jest, možete baciti coll čak i za unos Object. Prevoditelj će preskočiti svaku referencu na klasu roditelja, ili roditelj-roditelj, ili roditelj-roditelj ... roditelj

2. Pozivanje na polje - uvijek se vraća referentno polje, a ne polje objekta. Ako takvo polje ne postoji u referentnoj klasi, doći će do pogreške kompilacije.

Klasa A (int x = 2; // Polje roditelja) Klasa B proširuje A (int x = 3; // Polje koje bi se trebalo preklapati s nadređenim int y = 5; // Polje koje nije u nadređenoj klasi.) Test klase (javni statički void main (String args) (A ab = novi B (); // Pretvorba prema gore System.out.println ("Int x =" + ab.x);))

Će se vratiti Int x = 2 ... Ako pokušate pristupiti polju objekta:

System.out.println ("Int y =" + ab.y); // Pogreška kompilacije

Vaš prevodilac će reći da niste u pravu, jer ne vidi takvo polje kao referencu (A ab). Sve gore navedeno ostaje važeće čak i ako su vaša polja označena statičkim modifikatorima.

3. Pozivanje nestatičke metode: u ovom slučaju, vratit će metodu objekta. Ali kada se pristupa statičkoj metodi, vraća referentnu metodu.

Klasa D (public void doSome () (// Nestatička metoda System.out.println ("Nestatički doSome iz D");) public static void Action () (// Statička metoda System.out.println ("statička radnja iz D" ");)) javna klasa Okey proširuje D (public void doSome () (System.out.println (" doSome from Okey ");) public static void Action () (System.out.println (" statična radnja iz Okey " );) public static void main (String args) (D o = new Okey (); o.doSome (); // Iz klase Okey o.Action (); // Iz klase D))

Nestatički doSome od Okey

statična radnja iz D

Odgovor je jednostavan, nestatična metoda je metoda objekta, statička metoda je metoda klase. Kada pozovemo nestatičku metodu, prevodilac razumije ovo: leti kao vrana. Kada nazivamo statičnim – doslovno, leti kao ptica.

4. Ako postoji poziv metode koja je opisana u klasi objekata, ali nije opisana u referentnoj klasi, dogodit će se pogreška kompilacije. Jer, metoda se poziva referencom:

Klasa A () Klasa B proširuje A (void someMethod () (); public static void main (String args) (A ab = new B (); ab.someMethod (); // Greška kompilacije.))

5. Konstruktor objekta (kada je kreiran novom naredbom) radi isto kao da date referencu na svoju klasu.

Ponekad postoje situacije kada imate vrijednost određene vrste, a trebate je dodijeliti varijabli drugog tipa. Za neke tipove to se može učiniti bez pretvorbe tipa, u takvim slučajevima govorimo o automatskoj pretvorbi tipa. U Javi je automatska konverzija moguća samo ako je preciznost odredišne ​​varijable dovoljna za pohranu izvorne vrijednosti. Takva pretvorba se događa, na primjer, kada se literalna konstanta ili vrijednost varijable tipa byte ili short unese u varijablu tipa int. To se zove proširenje (proširenje) ili povećati (promocija), budući da se tip s manjom dubinom bita proširuje (povećava) na veći kompatibilni tip. Veličina tipa int uvijek je dovoljna za pohranjivanje brojeva u rasponu dopuštenom za bajt tipa, stoga, u takvim situacijama, eksplicitni operator cast nije potreban. Obrnuto nije točno u većini slučajeva, pa morate koristiti cast operator za bacivanje int vrijednosti u bajt varijablu. Ovaj postupak se ponekad naziva sužavanje (sužavanje), jer izričito govorite prevoditelju da pretvori vrijednost da stane u varijablu željenog tipa. Da biste doveli vrijednost na određeni tip, morate navesti ovu vrstu, zatvorenu u zagradama, ispred nje. Sljedeći isječak koda pokazuje prijenos od izvora (varijable tipa int) do vrste odredišta (varijable tipa bajt). Ako bi tijekom takve operacije cjelobrojna vrijednost izašla iz raspona dopuštenog za tip bajta, ona bi se smanjila dijeljenjem modula s rasponom dopuštenim za bajt (rezultat dijeljenja po modulu brojem je ostatak dijeljenja s ovim broj),

int a = 100;
bajtb = (bajt) a;

2.2.1. Automatska konverzija tipova u izrazima

Prilikom procjene vrijednosti izraza, preciznost potrebna za pohranjivanje međurezultata često mora biti veća od one potrebne za predstavljanje konačnog rezultata,

bajt a = 40;
bajt b = 50;
bajt sa = 100;
int d = a * b / s;

Rezultat srednjeg izraza (a * b) može izaći izvan raspona vrijednosti dopuštenih za tip bajta. To je razlog zašto Java automatski promovira svaki dio izraza u int, tako da ima dovoljno mjesta za međurezultat (a * b).

Automatska pretvorba tipa ponekad može uzrokovati neočekivane poruke o pogreškama prevoditelja. Na primjer, kod prikazan u nastavku, iako izgleda sasvim ispravno, rezultira porukom o pogrešci tijekom faze prijevoda. U njemu pokušavamo upisati vrijednost 50 * 2, koja bi se trebala savršeno uklopiti u tip bajta, u bajt varijablu. Ali zbog automatske konverzije vrste rezultata u int, primamo poruku o pogrešci od prevoditelja - uostalom, kada se int unese u bajt, može doći do gubitka preciznosti.

bajt b = 50;
b = b * 2:
^ Nekompatibilan tip za =. Eksplicitno prebacivanje potrebno za pretvaranje int u bajt.
(Nekompatibilan tip za =. Potrebna je eksplicitna konverzijaint ubajt)

Ispravljen tekst:
bajtb = 50;
b = (bajt) (b * 2);

što uzrokuje da b unese ispravnu vrijednost od 100.

Ako izraz koristi varijable tipa byte, short i int, tada se tip cijelog izraza automatski promiče u int kako bi se izbjeglo prelijevanje. Ako je tip barem jedne varijable u izrazu dug, tada se tip cijelog izraza također promiče u dug. Zapamtite da su svi cjelobrojni literali koji ne završavaju s L (ili 1) int.

Ako izraz sadrži operande tipa float, tada se tip cijelog izraza automatski promiče u float. Ako je barem jedan od operanada tipa double, tada se tip cijelog izraza promovira u double. Prema zadanim postavkama, Java sve literale s pomičnim zarezom tretira kao dvostruke. Sljedeći program pokazuje kako se tip svake vrijednosti u izrazu promovira tako da odgovara drugom operandu svakog binarnog operatora.

razred promovira (
javni statički void main (String args) (
bajt b = 42;
char with= "a";
kratke hlače = 1024;
int i = 50000;
plovak f = 5,67f;
udvostručeno = .1234;
dvostruki rezultat = (f * b) + (i / c) - (d * s);
Sustav, van. println ((f * b) + "+" + (i / c) + "-" + (d * s));
Sustav, van. println ("rezultat =" + rezultat); )
}

Podizraz f * b je float pomnožen bajtom, pa se automatski promiče u float. Sljedeći podizraz i / c (int podijeljen sa char) promovira se u int. Isto tako, tip podizraza d * s (dvostruko kratko) se promiče u dvostruko. U sljedećem koraku proračuna bavimo se tri međurezultata tipova float, int i double. Prvo, kada se prva dva zbroje, tip int se promovira u float i rezultat je tip float. Kada se od nje oduzme dvostruka vrijednost, vrsta rezultata se promiče u dvostruku. Konačni rezultat cijelog izraza je dvostruk.

Sada kada smo upoznati sa svim jednostavnim tipovima, uključujući cijele i realne brojeve, simbole i logičke varijable, pokušajmo spojiti sve informacije. Sljedeći primjer stvara varijable svakog od jednostavnih tipova i ispisuje vrijednosti tih varijabli.

klasa SimpleTypes (
javni statički void main (String args) (
bajt b = 0x55;
kratko s = 0x55ff;
int i = 1000000;
dugo l = 0xffffffffL;
char with= 'A';
float f = .25f;
dvostruki d = .00001234;
boolean bool = istina;
System.out.println ("bajt b =" + b);
System.out.println ("kratki s =" + s);
System.out.println ("int i =" + i);
System.out.println ("dugo 1 =" + l);
System.out.println ("char with= ”+ S);
System.out.println ("float f =" + f);
System.out.println ("dvostruki d =" + d);
System.out.println ("boolean bool =" + bool);)
}

Pokretanjem ovog programa trebali biste dobiti rezultat prikazan u nastavku:

bajt b = 85
kratke hlače = 22015
int i = 1000000
dugo 1 = 4294967295
char with= a
float f = 0,25
dvostruki d = 1,234e-005
boolean bool = istina

Imajte na umu da se cijeli brojevi ispisuju u decimalnom zapisu, iako smo za neke od njih naveli vrijednosti u heksadecimalnom zapisu.

Posljednje ažuriranje: 29.10.2018

Svaki osnovni tip podataka zauzima određeni broj bajtova memorije. To postavlja ograničenje na operacije koje uključuju različite vrste podataka. Razmotrimo sljedeći primjer:

Int a = 4; bajt b = a; //! Greška

U ovom kodu naići ćemo na pogrešku. Iako i bajt i int predstavljaju cijele brojeve. Štoviše, vrijednost varijable a, koja je dodijeljena varijabli tipa bajta, dobro je unutar raspona vrijednosti za tip bajta (od -128 do 127). Međutim, nailazimo na pogrešku u vremenu prevođenja. Jer u ovom slučaju pokušavamo dodijeliti neke podatke koji imaju 4 bajta varijabli koja ima samo 1 bajt.

Međutim, vaš program će možda morati izvršiti ovu konverziju. U ovom slučaju, moram koristiti operaciju konverzije tipa (operacija ()):

Int a = 4; bajt b = (bajt) a; // konverzija tipa: iz int u bajt System.out.println (b); // 4

Operacija pretvorbe tipa podrazumijeva naznaku u zagradama tipa u koji se vrijednost treba pretvoriti. Na primjer, u slučaju (bajt) operacije, tip podataka int se pretvara u tip bajta. Kao rezultat, dobivamo vrijednost bajta.

Eksplicitne i implicitne pretvorbe

Kada su podaci različitih tipova uključeni u istu operaciju, nije uvijek potrebno koristiti operaciju pretvorbe tipa. Neke vrste pretvorbi izvode se implicitno, automatski.

Automatske konverzije

Strelice na slici pokazuju koje se pretvorbe tipa mogu izvesti automatski. Isprekidane strelice pokazuju automatske pretvorbe s gubitkom preciznosti.

Automatski proizvedeno bez ikakvih problema proširenja transformacija(proširivanje) - proširuju prikaz objekta u memoriji. Na primjer:

Bajt b = 7; int d = b; // pretvoriti iz bajta u int

U ovom slučaju, bajt, koji zauzima 1 bajt u memoriji, proširuje se na int, koji zauzima 4 bajta.

Proširene automatske transformacije predstavljene su sljedećim lancima:

bajt -> kratko -> int -> dugo

int -> duplo

kratko -> plutajući -> dvostruko

char -> int

Automatske pretvorbe s gubitkom preciznosti

Neke se pretvorbe mogu izvršiti automatski između tipova podataka iste dubine bita, ili čak iz vrste podataka s većom dubinom bita u tip s nižom dubinom bita. To su sljedeći lanci konverzija: int -> float, long -> float i long -> double izvode se bez grešaka, ali možemo se suočiti s gubitkom informacija tijekom pretvorbe.

Na primjer:

Int a = 2147483647; plutaju b = a; // od int do float System.out.println (b); // 2.14748365E9

Eksplicitne konverzije

Sve ostale primitivne pretvorbe tipa eksplicitno primjenjuju definiciju pretvorbe tipa. Obično se radi o sužavajućim pretvorbama iz vrste s većom dubinom bita u tip s manjom dubinom bita:

Dugi a = 4; int b = (int) a;

Gubitak podataka tijekom pretvorbe

Kada koristimo eksplicitne transformacije, možemo doživjeti gubitak podataka. Na primjer, sa sljedećim kodom nećemo imati problema:

Int a = 5; bajt b = (bajt) a; System.out.println (b); // 5

Broj 5 dobro se uklapa u raspon vrijednosti tipa bajta, pa će nakon konverzije varijabla b biti 5. Ali što se događa u sljedećem slučaju:

Int a = 258; bajt b = (bajt) a; System.out.println (b); // 2

Rezultat je 2. U ovom slučaju, 258 je izvan raspona za bajt (-128 do 127), pa će vrijednost biti skraćena. Zašto je rezultat upravo broj 2?

Broj a, koji je 258, u binarnom obliku bit će 00000000 00000000 00000001 00000010. Vrijednosti bajtova zauzimaju samo 8 bita u memoriji. Stoga se binarni prikaz int skraćuje na desnih 8 znamenki, odnosno 00000010, što daje 2 u decimalnom obliku.

Skraćivanje racionalnih brojeva na cijele brojeve

Prilikom pretvaranja vrijednosti s pomičnim zarezom u cjelobrojne vrijednosti, razlomak se skraćuje:

Dvostruko a = 56,9898; int b = (int) a;

Ovdje bi b bilo 56, iako bi 57 bilo bliže 56,9898. Da biste izbjegli takve incidente, morate koristiti funkciju zaokruživanja koja se nalazi u Java matematičkoj biblioteci:

Dvostruko a = 56,9898; int b = (int) Math.round (a);

Transformacije u operacijama

Često postoje situacije kada morate primijeniti različite operacije, na primjer, zbrajanje i proizvod, na vrijednosti različitih vrsta. Ovdje također vrijede neka pravila:

    ako je jedan od operanada operacije dvostrukog tipa, tada se i drugi operand također pretvara u dvostruki tip

    ako prethodni uvjet nije ispunjen, a jedan od operanada operacije je tipa float, tada se drugi operand također pretvara u tip float

    ako prethodni uvjeti nisu ispunjeni, jedan od operanada operacije je tipa long, tada se drugi operand također pretvara u tip long

    inače se svi operandi operacije pretvaraju u tip int

Primjeri transformacija:

Int a = 3; dvostruko b = 4,6; dvostruko c = a + b;

Budući da operacija uključuje dvostruku vrijednost, druga vrijednost se prebacuje na tip double, a zbroj dviju vrijednosti a + b predstavlja dvostruki tip.

Još jedan primjer:

Bajt a = 3; kratko b = 4; bajt c = (bajt) (a + b);

Dvije su varijable tipa byte i kratke (ne double, float ili long), tako da se pretvaraju u int kada se dodaju, a njihov zbroj a + b predstavlja int. Stoga, ako zatim dodijelimo ovaj zbroj varijabli tipa byte, onda ponovno trebamo izvršiti pretvorbu tipa u bajt.

Ako operacije uključuju podatke tipa char, tada se pretvaraju u int:

Int d = "a" + 5; System.out.println (d); // 102

Vrhunski povezani članci