Kako podesiti pametne telefone i računare. Informativni portal

Java dvostruka konverzija 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 sam Java runtime sistem implicitno izvodi takve konverzije.

Konverzija tipa T 1 do tipa T 2 omogućava da se izraz tipa T 1 tretira u vrijeme kompajliranja kao izraz tipa T 2 . U nekim slučajevima ovo je čisto sintaktička konstrukcija koja ne utječe na generirani kod, u drugim je potrebna konverzija tipa dodatne radnje tokom izvršenja za promjenu vrijednosti izraza ili dodatne provjere ispravnosti primijenjene transformacije. primjeri:

  • Konverzija tipa int u tipu dugo zahtijeva proširenje predznaka 32-bitne vrijednosti cijelog broja na 64-bitni cijeli broj pri izvršavanju programa. Nema gubitka informacija.
  • Konverzija tipa float u tipu dugo zahtijeva netrivijalnu konverziju iz 32-bitne plutajuće vrijednosti u 64-bitni cijeli broj pri izvršavanju programa. Ovisno o originalnoj vrijednosti, gubitak informacija može, ali ne mora doći.
  • Pretvaranje tipa Thread u tip Object ne zahtijeva nikakvu radnju: Budući da je klasa Thread potomak klase Object, svaka referenca na objekt tipa Thread je automatski referenca na objekt tipa Object.
  • Konverzija iz tipa objekta u tip Thread zahtijeva provjeru u vrijeme izvođenja. Ako je referenca koja se konvertuje zaista referenca na objekat tipa Thread, onda se vraća kao rezultat konverzije, u suprotnom se stvara izuzetak.

5.4.1.1. Proširivanje transformacija brojeva

Proširivanje transformacija brojeva to su konverzije iz numeričkog tipa u „veći“ numerički tip, koje se smatraju sigurnim jer ne dovode do gubitka veličine pretvorene vrijednosti. Takve konverzije u Javi su:

  • transformacija bajt V kratko, int, dugo, float I duplo;
  • transformacija kratko V int, dugo, float I duplo;
  • transformacija char V int, dugo, float I duplo;
  • transformacija int V dugo, float I duplo;
  • transformacija dugo V float I duplo;
  • transformacija float V duplo.

Zapravo, pretvaranje cjelobrojne vrijednosti u plutajuću vrijednost može rezultirati gubitkom preciznosti, tj. značajne figure. Dakle, sljedeći primjer

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

će prikazati string 1234567936. To je zbog činjenice da prilikom pretvaranja int V float rezultirajuća vrijednost je 1,2345679E9 zbog činjenice da je mantisa brojeva poput float prima samo 8 decimalnih cifara (ovdje za pravilan rad treba koristiti konverziju tipa duplo). Međutim, runtime sistem nikada ne generiše greške prilikom izvođenja ovih transformacija.

5.4.1.2. Sužavanje konverzija brojeva

Sužavanje konverzija brojeva To su konverzije iz numeričkog tipa u "manji" numerički tip, što može rezultirati i gubitkom veličine i gubitkom preciznosti. Takve konverzije u Javi su:

  • transformacija bajt V char;
  • transformacija kratko V bajt I char;
  • transformacija int V bajt, kratko I char;
  • transformacija dugo V bajt, kratko, int I char;
  • transformacija float V bajt, kratko, int, dugo I char;
  • transformacija duplo V bajt, kratko, int, dugo, float I char;

Ovdje nećemo detaljno razmatrati pravila po kojima se te transformacije dešavaju, budući da su intuitivno jasna, ali formalno prilično glomazna. Kada ih koristite, važno je imati na umu da Java, za razliku od drugih jezika, ne generiše greške pri prepunjavanju ili nedostatku, tako da kontrola ispravnosti transformacija u potpunosti pada na programera.

5.4.1.3. Proširivanje transformacija veze

Proširivanje transformacija veze Ovo su konverzije izvedenih referentnih tipova u njihove tipove pretka koje ne zahtijevaju radnju vremena izvođenja i nikada ne generiraju greške. Takve konverzije u Javi su:

  • pretvaranje bilo koje klase ili interfejsa u njenog pretka (posebno u tip Object);
  • pretvaranje klase u interfejs koji 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, a pretvaranje S u T se širi;
  • Pretvaranje nulte vrste u bilo koji referentni tip.

5.4.1.4. Transformacije veza za sužavanje

Transformacije veza za sužavanje ovo su konverzije izvedenih referentnih tipova u tipove njihovih potomaka. Ove konverzije zahtijevaju provjeru njihove legitimnosti u vremenu izvođenja i mogu izazvati ClassCastException. Takve konverzije u Javi su:

  • pretvaranje bilo koje klase u njenog potomka (posebno, pretvaranje tipa Object u bilo koju drugu klasu);
  • pretvaranje klase u interfejs kada klasa nije konačna i ne implementira interfejs (posebno, pretvaranje tipa Object u bilo koji interfejs);
  • pretvaranje tipa objekta u bilo koji niz;
  • pretvaranje bilo kojeg interfejsa u klasu koja nije konačna;
  • pretvaranje bilo kojeg interfejsa u klasu koja je konačna i implementira dati interfejs;
  • pretvaranje interfejsa J u interfejs K kada J nije potomak K i ne postoji metoda deklarisana u J i K sa istim potpisom ali različitim tipovima rezultata;
  • pretvaranje niza tipa S u niz tipa T ako su S i T referentni tipovi, a pretvaranje S u T je sužavanje.

5.4.1.5. Konverzije u nizove

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

5.4.1.6. Nevažeće konverzije

Sljedeće konverzije tipova su zabranjene 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 null tipa u bilo koji primitivni tip;
  • konverzije u null tip ili tip boolean;
  • konverzije tipova boolean na bilo koji tip osim String ;
  • pretvaranje jedne klase u drugu ako nijedna nije predak druge (osim pretvaranja u String);
  • pretvaranje klase u interfejs ako je klasa konačna i ne implementira se ovaj interfejs;
  • pretvaranje klase u niz ako je klasa drugačija od Object ;
  • pretvaranje interfejsa u klasu koja je konačna i ne implementira dati interfejs (osim konverzije u tip String);
  • pretvaranje interfejsa J u interfejs K ako postoji metoda deklarisana u J i K sa istim potpisom, ali različitim tipovima rezultata;
  • pretvaranje niza u klasu koja nije Object i String;
  • pretvaranje niza u interfejs koji se ne može klonirati;
  • pretvaranje niza tipa S u niz tipa T ako je pretvaranje S u T nezakonito

5.4.2. Konteksti transformacije

5.4.2.1. Konverzija na zadatku

Konverzija na zadatku javlja se kada je vrijednost izraza dodijeljena varijabli. U ovom slučaju, tip izraza se pretvara u tip varijable. Prilikom dodjele, uvijek su moguće proširene konverzije tipova (i numeričkih i referentnih). Sužavajuća transformacija je moguća samo ako su ispunjeni sljedeći uvjeti:

  • varijabla ima tip bajt, kratko ili char;
  • vrijednost izraza je konstanta tipa int, koji spada u raspon moguće vrijednosti varijabla.

Na primjer, bajt operatora x = 123; prihvatljivo, budući da je konstanta 123 (tipa int) leži u opsegu prihvatljive vrijednosti tip bajt.

Ako se tip izraza ne može pretvoriti u tip varijable, kompajler generiše grešku. U drugim slučajevima kažemo da je tip izraza kompatibilan sa zadatkom sa tipom varijable. Dakle, sledeći fragment

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

će generirati grešku jer tipovi char I kratko su dodjela nekompatibilna prema gore datim definicijama (prva je implementirana kao neoznačene 16-bitne riječi, a druga kao predpisana).

5.4.2.2. Pretvaranje argumenata metode

Pretvaranje argumenata metode javlja se kada se stvarne vrijednosti argumenata konvertuju u tip parametara metode ili konstruktora kada se on pozove. U ovom slučaju, proširene konverzije tipova (i numeričkih i referentnih) su uvijek moguće, a sužene konverzije nisu dozvoljene. Razlozi najnovije zabrane mogu se objasniti sljedeći primjer:

Test klase ( static int m(byte a, int b) ( return a + b; ) static int m(short a, short b) ( return a - b; ) public static void main (String args) ( System.out. println( m(1, 2)); // generiše grešku kompilacije ) )

Ovdje klasa Test sadrži dvije metode istog imena, koje se razlikuju samo po tipovima parametara. Ako su konverzije argumenata za sužavanje dozvoljene u Javi, vrijeme izvođenja bi moralo odrediti na koje se od ovih metoda odnosi poziv m(1, 2). Da bi izbjegli takve nejasnoće, programeri jezika su radikalno riješili problem: zabranili su takve pozive metoda. U ovoj situaciji, da bismo pozvali, na primjer, prvu metodu, moramo eksplicitno naznačiti tip prvog operanda (drugi po defaultu već ima tip int), naime m((bajt)1, 2) .

5.4.2.3. Pretvori u niz

Pretvori 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đe konvertuje u tip String, a rezultat operacije je konkatenacija rezultujućih stringova. Ovaj proces je detaljnije opisan u Pogl. 5.14.

5.4.2.4. Eksplicitna konverzija tipa

Eksplicitna konverzija tipa Javlja se kada se operacija pretvaranja tipa eksplicitno primjenjuje na operand. U ovoj situaciji mogu se koristiti sve gore opisane vrste konverzije tipova, osim pretvaranja u string. Pokušaj eksplicitne konverzije u tip označen kao zabranjen iznad će uzrokovati grešku kompilacije. Dodatno, ClassCastException može biti izbačen u vrijeme izvođenja ako navedena konverzija nije važeća.

5.4.3. Brojčane konverzije tipa operanda

Konverzija tipa tokom evaluacije numeričke izraze ima niz karakteristika. Oni se svode na dva slučaja: konverzija operanda u unarnim operacijama i u binarnim operacijama.

Prije izvršenja unarnu operaciju:

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

Prije izvođenja binarne operacije:

  • ako je jedan od operanda tipa duplo, onda se i drugi pretvara u tip duplo;
  • float, onda se i drugi pretvara u tip float;
  • inače, ako je jedan od operanda tipa dugo, onda se i drugi pretvara u tip dugo;
  • u suprotnom, oba operanda se pretvaraju u tip int.

Ovo je prilično velika tema, ali pokušat ćemo je razmotriti što potpunije i istovremeno kompaktnije. Već smo se delimično dotakli ove teme kada smo gledali primitivne Java tipove.

U Javi su moguće konverzije između vrijednosti cijelog broja i vrijednosti s pomičnim zarezom. Osim toga, možete pretvoriti vrijednosti cijelih brojeva i vrijednosti s pomičnim zarezom u vrijednosti char i obrnuto, jer svaki znak odgovara cifri u Unicode kodiranje. U stvari, boolean tip je jedini primitivni tip u Javi koji se ne može konvertovati u drugi primitivni tip. Dodatno, bilo koji drugi primitivni tip ne može se pretvoriti u boolean.

Postoje dvije vrste konverzije tipova u Javi: implicitno I eksplicitno.

Implicitna konverzija tipa se izvršava ako su ispunjeni sljedeći uslovi:

  1. Oba tipa su kompatibilna
  2. Dužina tip cilja veća ili jednaka dužini originalnog tipa

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

Postoje i dvije vrste transformacija:

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

Proširujuća transformacija ( proširenje konverzije) se javlja kada se vrijednost jednog tipa konvertuje u širi tip, s većim rasponom važećih vrijednosti. Java automatski vrši konverzije proširenja, na primjer ako dodijelite literal tipa int varijabilni tip double ili vrijednost varijable tipa char tipa int. Implicitna konverzija uvijek ima tip ekstenzije.

Ali ovo može imati svoje male grabulje. Na primjer, ako se int vrijednost konvertuje u float vrijednost. A vrijednost int u binarnom predstavljanju je veća od 23 značajni bitovi, tada je moguć gubitak preciznosti, budući da tip float ima 23 bita dodijeljena za cijeli broj. Svi niski bitovi int vrijednosti koje se ne uklapaju u 23 bita float mantise bit će odbačene, pa će, iako će red broja biti sačuvan, preciznost biti izgubljena. Isto vrijedi i za pretvaranje dugog tipa u double.

Proširujuća transformacija Java tipovi može se prikazati i ovako:

Pune linije označavaju transformacije izvedene bez gubitka podataka. Isprekidane linije označavaju da može doći do gubitka preciznosti tokom konverzije.

Vrijedi malo objasniti zašto se, na primjer, tip bajta ne konvertuje automatski (ne eksplicitno) u tip char, iako tip bajta ima širinu od 8 bita, a char je 16, isto važi i za konverziju kratki tip za char. Ovo se dešava zato što su bajt i kratki tipovi podataka potpisani, a char je nepotpisan. Stoga, u u ovom slučaju Morate koristiti eksplicitno uvođenje tipova jer morate eksplicitno reći kompajleru da znate šta želite i kako će se bitovima predznaka bajtova i kratkih tipova rukovati prilikom pretvaranja u char.

Ponašanje vrijednosti char je u većini slučajeva isto kao i ponašanje vrijednosti cjelobrojnog tipa, stoga se vrijednost char može koristiti gdje god je potrebna int ili long vrijednost. Međutim, zapamtite da je tip char bez predznaka, tako da se ponaša drugačije od kratkog tipa, iako oba tipa imaju raspon od 16 bita.

kratko s = ( kratko ) 0xffff; // Ovi bitovi predstavljaju broj –1
char c = "\uffff"; // Isti bitovi predstavljaju unikod karakter
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 javlja kada se vrijednost konvertuje u vrijednost tipa čiji raspon nije širi od originalnog. Pretvorbe sužavanja nisu uvijek sigurne: na primjer, pretvaranje cjelobrojne vrijednosti 13 u bajt ima smisla, ali pretvaranje 13000 u bajt nije mudro, jer bajt može pohraniti samo brojeve od −128 do 127. Budući da podaci mogu biti izgubljeni tokom sužavanja konverziju, Java kompajler se protivi svakoj takvoj konverziji, čak i ako vrijednost koja se pretvara spada u uži raspon specificiranog tipa:

int i = 13 ;
bajt b = i ; // Kompajler neće dozvoliti ovaj izraz

Jedini izuzetak od pravila je kada se dodijeli cijeli literal (vrijednost int) bajtu ili kratkoj varijabli ako literal odgovara rasponu varijable.

Sužavajuća konverzija je uvijek eksplicitna konverzija tipa.

Eksplicitna konverzija primitivni tipovi

Operator eksplicitne konverzije tipa, tačnije, ulijevanja tipa je okrugle zagrade, unutar kojeg je naznačen tip na koji se vrši konverzija - (vrsta). Na primjer:

int i = 13 ;
bajt b = ( bajt ) i ; // Prisilno pretvaranje iz int u bajt
i = ( int ) 13.456 ; // Prisilna konverzija dvostrukog literala u int 13

Najčešće se koristi lijevanje primitivnog tipa za pretvaranje vrijednosti s pomičnim zarezom u cijele brojeve. Gde frakcija vrijednosti s pomičnim zarezom se jednostavno odbacuju(to jest, vrijednost s pomičnim zarezom je zaokružena prema nuli, a ne prema najbližem cijelom broju). Esencijalno uzima se samo cijeli broj pravi tip i već je prebačen na ciljni cjelobrojni tip.

Prilikom donošenja većeg kapaciteta ceo tip kod manjeg kapaciteta, najvažniji bitovi se jednostavno odbacuju. U suštini, ovo je ekvivalentno operaciji dijeljenja po modulu vrijednosti koja se smanjuje za raspon ciljnog tipa (na primjer, za tip bajta to je 256).

Prevelike razlomak broj kada se prebaci na cijeli broj postaje MAX_VALUE ili MIN_VALUE.

Prevelike duplo kada se dovede do float pretvara se u Float.POSITIVE_INFINITY ili Float.NEGATIVE_INFINITY.

Tabela ispod je mreža u kojoj su, za svaki primitivni tip, naznačeni tipovi u koje se mogu konvertovati i način konverzije. Pismo N u tabeli znači da konverzija nije moguća. Pismo Y znači proširenu transformaciju koja se izvodi automatski. Pismo WITH znači sužavanje transformacije koja zahtijeva eksplicitni cast. konačno, Y* znači automatsku transformaciju proširenja, tokom koje vrijednost može izgubiti neke od svojih najmanje značajnih cifara. Ovo se može dogoditi kada se int ili long pretvara u float ili double. Tipovi s pomičnim zarezom imaju veći raspon od integer tipova, tako da int ili long mogu biti predstavljeni pomoću float ili double. Međutim, tipovi s pomičnim zarezom su aproksimacije brojeva i ne moraju uvijek sadržavati toliko značajnih cifara u mantisi kao cjelobrojni tipovi.

Automatsko proširenje tipa u izrazima

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

Odnosno, svi cjelobrojni literali u izrazima, kao i tipovi bajt, kratko I char proširiti na int . Ako, kao što je gore opisano, izraz ne sadrži druge, više velike vrste podaci ( dugo, float ili duplo). Stoga će gornji primjer uzrokovati grešku kompilacije jer je varijabla c ima tip bajt, a izraz b+1, kao rezultat automatske promocije, ima tip int.

Implicitno uvođenje tipa u mješovitim izrazima dodjeljivanja

Mada ovaj odeljak i odnosi se na implicitna konverzija(casting) tipova, ovdje smo dali njegovo objašnjenje, budući da u ovom slučaju funkcionira i automatsko proširenje tipa u izrazima, a zatim i implicitno uvođenje tipa. Ovo je kor de balet. Mislim da će primjer u nastavku sve pojasniti. Kao iu prethodnom objašnjenju, znak @ znači bilo koji važeći operator, na primjer + , , * , / i tako dalje.

Ovo vrijedi objasniti jednostavnim primjerom:

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

Drugi red dat u primjeru se ne kompajlira zbog automatskog proširenja tipa u izrazima, pošto je izraz b2*2 tipa int, jer dolazi do automatskog proširenja tipa (cijelobrojni literali u izrazu su uvijek int). Treći red će se lako kompajlirati, budući da će implicitno uvođenje tipa u kombinovanom izrazu dodjeljivanja raditi u njemu.

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

Boks i raspakivanje su također prilično velika tema, ali je prilično jednostavna.

Esencijalno boksovanje i raspakivanje su konverzije iz primitivnih tipova u objekte omotača i nazad.

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

Klase omotača su spomenute u tabelama kada se analizira svaki od primitivnih tipova. Ali tada je to bilo samo pominjanje u tabeli.

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

Obično, ako program ima puno matematičkih proračuna, onda je bolje koristiti primitivne tipove, jer je to brže i ekonomičnije u smislu resursa, ali ponekad postoji potreba da se primitivni tip pretvori u objekt.

Dozvolite mi da vam dam jednostavan primjer:

int i3 ;
bajt b2 = 3 ;
Byte myB ;
myB= b2;
myB++;
b2= myB;
i3= myB;

Ako još nije jasno zašto je to potrebno, onda nije strašno, samo vežite čvor za pamćenje.

Prethodni govornik je prilično u potpunosti opisao silaznu transformaciju, ali transformacija prema gore (po mom mišljenju) zahtijeva dodatno objašnjenje, jer je pitanje vrlo popularno i zanimljivo.

Kako funkcionira eksplicitno uvođenje tipova

Vaš primjer pokazuje transformaciju naviše ( Upcasting):

List coll = new ArrayList();

Na ruski se prevodi na sljedeći način: stvori vranu, poput ptice. Kreirajte dinamički niz, poput lista. U većini situacija, konverzija naviše je potpuno nepotrebna.
Međutim, uvođenje tipova funkcionira u intervjuima kada vam se daju pitanja o nasljeđivanju. Na primjer, web stranica quizful.net općenito sadrži mnogo pitanja o tipovima. Stoga ću objasniti karakteristike koje poznajem.

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

1. Veza može biti usmjerena na bilo kojeg roditelja. Čak i veoma davno. To jest, možete baciti referencu coll čak i na tip Object. Kompajler će preskočiti svaku referencu na roditeljsku klasu, ili roditelj-roditelj, ili roditelj-roditelj...roditelj

2. Kada se pristupa polju, uvijek se vraća referentno polje, a ne polje objekta. Ako takvo polje ne postoji u referentnoj klasi, doći će do greške pri kompilaciji.

Klasa A( int x = 2; //Polje roditelja) Klasa B proširuje A ( int x = 3; //Polje koje bi trebalo da se preklapa s nadređenim int y = 5; //Polje koje nije u roditeljskoj klasi. ) Test klase ( public static void main(String args) ( A ab = new B(); // Konverzija naviše 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); //Greška kompilacije

Vaš kompajler će reći da niste u pravu, jer ne vidi takvo polje u linku (A ab). Sve gore navedeno ostaje važeće čak i ako svoja polja označite statičkim modifikatorima.

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

Class D( public void doSome())( //Nestatička metoda System.out.println("Nestatična doSome iz D"); ) public static void Action())( //Statička metoda System.out.println("statička akcija iz D "); ) ) javna klasa Okey proširuje D( public void doSome())( System.out.println("doSome from Okey"); ) public static void Action())( System.out.println("static Akcija 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čka akcija od D

Rješenje je jednostavno, nestatična metoda je objektna metoda, statička metoda je metoda klase. Kada pozovemo nestatičku metodu, kompajler razume ovo: leti kao vrana. Kada nazivamo statičnim - bukvalno, leti kao ptica.

4. Ako postoji poziv metode koja je opisana u klasi objekata, ali nije opisana u referentnoj klasi, doći će do greške kompilacije. Zato što se metoda 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 objekata (kada je kreiran novom komandom) radi isto kao da date vezu na svoju klasu.

Ponekad se pojave situacije kada imate neku vrijednost određeni tip, ali morate ga dodijeliti varijabli drugog tipa. Za neke tipove to se može učiniti bez uvođenja tipova u takvim slučajevima govore o automatskoj konverziji tipa. U Javi, automatska konverzija je moguća samo ako je numerički prikaz odredišne ​​varijable dovoljno precizan da pohrani originalnu vrijednost. Takva konverzija se događa, na primjer, kada se unese literalna konstanta ili vrijednost varijable tipa byte ili short u varijablu tipa int. To se zove proširenje (proširenje) ili povećati (promocija), jer je tip nižeg bita proširen (promoviran) u veći kompatibilni tip. Veličina tipa int je uvijek dovoljna za pohranjivanje brojeva iz raspona dozvoljenog tipom bajta, dakle in slične situacije Eksplicitni operator cast tipa nije potreban. Obrnuto nije tačno u većini slučajeva, pa da biste dodelili vrednost tipa int promenljivoj tipa bajt, morate koristiti operator cast tipa. Ova procedura se ponekad naziva sužavanje (sužavanje), jer izričito govorite prevodiocu da vrijednost treba konvertirati da bi se uklopila u varijablu željenog tipa. Da biste prebacili vrijednost na određeni tip, prethodite joj navođenjem tog tipa, zatvorenog u zagradama. Sljedeći isječak koda pokazuje pretvaranje tipa izvora (int varijable) u tip odredišta (bajt varijabla). Ako bi, tokom takve operacije, vrijednost cijelog broja bila izvan raspona dozvoljenog za tip bajta, ona bi se smanjila modulo dijeljenjem rasponom dozvoljenim za bajt (rezultat modulo dijeljenja brojem je ostatak dijeljenja sa taj broj),

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

2.2.1. Automatska konverzija tipova u izrazima

Prilikom izračunavanja 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 / c;

Rezultat srednjeg izraza (a*b) može biti izvan raspona vrijednosti dozvoljenih za tip bajta. To je razlog zašto Java automatski promoviše tip svakog dijela izraza u tip int, tako da ima dovoljno mjesta za srednji rezultat (a* b).

Automatska konverzija tipa ponekad može uzrokovati neočekivane poruke o grešci prevodioca. Na primjer, kod prikazan ispod, iako izgleda sasvim ispravno, rezultira porukom o grešci tokom faze prevođenja. 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 tipa rezultata u int, primamo poruku o grešci od prevoditelja - na kraju krajeva, prilikom pisanja int 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 inbajt)

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

što uzrokuje da se b postavi na ispravnu vrijednost 100.

Ako izraz koristi varijable tipa byte, short i int, tada se tip cijelog izraza automatski promovira u int kako bi se izbjeglo prelivanje. Ako je u izrazu tip barem jedne varijable dug, tada se i tip cijelog izraza podiže na long. Zapamtite da su svi cjelobrojni literali koji se ne završavaju sa L (ili 1) tipa int.

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

razred promovira (
public static void main (String args) (
bajt b= 42;
char with= "a';
šorc = 1024;
int i = 50000;
float f = 5,67f;
udvostručeno =.1234;
dvostruki rezultat = (f*b) + (i/ c) - (d* s);
Sistem, napolje. println ((f* b)+ "+ "+ (i / c)+ " -" + (d* s));
Sistem, napolje. println("rezultat = "+ rezultat); )
}

Podizraz f*b je float pomnožen bajtom, tako da se njegov tip automatski unapređuje u float. Tip sljedećeg podizraza i/c (int podijeljen sa char) se unapređuje u int. Slično, tip podizraza d*s (dvostruko kratko) se unapređuje u dvostruko. U sljedećem koraku proračuna bavimo se tri međurezultata tipova float, int i double. Prvo, kada se dodaju prva dva, tip int se unapređuje u float i rezultat je float. Kada se od nje oduzme dvostruka vrijednost, tip rezultata se unapređuje u duplo. Konačni rezultat cijelog izraza je dvostruka vrijednost.

Sada kada smo vidjeli sve jednostavne tipove, uključujući cijele brojeve, realne brojeve, znakove i logičke vrijednosti, pokušajmo to sve spojiti. Primjer ispod kreira varijable za svaku od njih jednostavni tipovi i prikazuju se vrijednosti ovih varijabli.

klasa SimpleTypes (
public static void main (String args) (
bajt b = 0x55;
kratki s = 0x55ff;
int i = 1000000;
dugo l = 0xffffffffL;
char with= 'a';
float f= .25f;
duplo d = .00001234;
boolean bool = istina;
System.out.println("bajt b = " + b);
System.out.println("short s = " +s);
System.out.println("int i =" + i);
System.out.println("long 1 = " + l);
System.out.println("char with=” + s);
System.out.println("float f = " + f);
System.out.println("double d = " + d);
System.out.println("boolean bool =" + bool); )
}

Pokretanjem ovog programa trebalo bi da dobijete izlaz prikazan ispod:

bajt b = 85
šorc = 22015
int i = 1000000
dugo 1 = 4294967295
char with= a
float f = 0,25
duplo d=1.234e-005
boolean boolean = istina

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

Posljednje ažuriranje: 29.10.2018

Svaki osnovni tip podaci zauzimaju određeni broj bajtova memorije. Ovo postavlja ograničenja na operacije koje uključuju Razne vrste podaci. Razmotrite sljedeći primjer:

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

U ovom kodu ćemo naići na grešku. Iako i tip bajta i tip int predstavljaju cijele brojeve. Štaviše, vrijednost varijable a, koja je dodijeljena varijabli tipa bajt, dobro je unutar raspona vrijednosti za tip bajt (od -128 do 127). Međutim, nailazimo na grešku tokom faze kompilacije. Jer u ovom slučaju pokušavamo dodijeliti neke podatke koji zauzimaju 4 bajta varijabli koja će uzeti samo jedan bajt.

Međutim, program može zahtijevati da se izvrši takva konverzija. U ovom slučaju, moram koristiti operaciju konverzije tipa (() operacija):

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

Operacija konverzije tipa uključuje navođenje u zagradama tipa u koji se vrijednost mora pretvoriti. Na primjer, u slučaju operacije (byte)a, podaci tipa int se pretvaraju u tip bajta. Kao rezultat, dobićemo vrijednost tipa byte.

Eksplicitne i implicitne konverzije

Kada jedna operacija uključuje podatke različite vrste, nije uvijek potrebno koristiti operaciju konverzije tipa. Neke vrste transformacija se izvode implicitno, automatski.

Automatske konverzije

Strelice na slici pokazuju koje se konverzije tipa mogu izvršiti automatski. Isprekidane strelice pokazuju automatske konverzije sa gubitkom preciznosti.

Automatski proizveden bez ikakvih problema proširene transformacije(proširivanje) - proširuju reprezentaciju objekta u memoriji. Na primjer:

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

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

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

bajt -> kratko -> int -> dugo

int -> duplo

kratko -> plutajući -> duplo

char -> int

Automatske konverzije sa gubitkom preciznosti

Neke konverzije se mogu izvršiti automatski između tipova podataka iste širine bita, ili čak iz tipa podataka sa većom širinom bita u tip sa manjom širinom bita. To su sljedeći lanci konverzija: int -> float, long -> float i long -> double se izvode bez grešaka, ali tokom konverzije možemo naići na gubitak informacija.

Na primjer:

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

Eksplicitne konverzije

Sve druge konverzije primitivnih tipova eksplicitno primjenjuju operaciju konverzije tipa. Obično su to sužavanje konverzija od tipa sa većom širinom bita u tip sa manjom širinom bita:

Dugačak a = 4; int b = (int) a;

Gubitak podataka tokom konverzije

Kada koristimo eksplicitne konverzije, možemo naići na gubitak podataka. Na primjer, nećemo imati problema sa sljedećim kodom:

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

Broj 5 se dobro uklapa u raspon vrijednosti bajtova, tako da će nakon konverzije varijabla b biti jednaka 5. Ali šta se događa u sljedećem slučaju:

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

Rezultat će biti broj 2. U ovom slučaju, broj 258 je izvan opsega za tip bajta (od -128 do 127), tako da će vrijednost biti skraćena. Zašto će rezultat biti broj 2?

Broj a, koji je 258, in binarni sistem biće jednako 00000000 00000000 00000001 00000010 . Vrijednosti bajtova zauzimaju samo 8 bita memorije. Zbog toga binarno predstavljanje int broj je skraćen na desno 8 cifara, odnosno 00000010 , što u decimalni sistem daje broj 2.

Skraćivanje racionalnih brojeva na cijele brojeve

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

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

Ovdje bi vrijednost b bila 56, iako bi 57 bilo bliže 56,9898. Da biste izbjegli takve incidente, trebate koristiti funkciju zaokruživanja koja je dostupna u matematička biblioteka Java:

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

Transformacije tokom operacija

Često postoje situacije kada je potrebno koristiti različite operacije, na primjer, zbrajanje i proizvod, na vrijednostima različitih tipova. I ovdje vrijede neka pravila:

    ako je jedan od operanada operacije tipa double, onda se drugi operand pretvara u tip double

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

    ako prethodni uslovi nisu ispunjeni, jedan od operanada operacije je tipa long , tada se drugi operand pretvara u tip long

    inače se svi operandi operacije konvertuju u tip int

Primjeri transformacija:

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

Budući da operacija uključuje dvostruku vrijednost, obje druge vrijednosti se pretvaraju u tip double, a zbir dviju vrijednosti a+b predstavlja dvostruki tip.

Drugi primjer:

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

Dvije varijable su tipa byte i kratke (ne double, float ili long), tako da se kada se dodaju pretvaraju u tip int, a njihov zbir a+b predstavlja vrijednost int. Stoga, ako zatim dodijelimo ovaj iznos varijabli tipa bajt, onda opet moramo izvršiti konverziju tipa u bajt.

Ako operacije uključuju podatke tipa char, oni se konvertuju u int:

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

Najbolji članci na ovu temu