Kako postaviti pametne telefone i računala. Informativni portal
  • Dom
  • OS
  • Prebacivanje niza u broj java. Pretvaranje Java nizova u druge vrste vrijednosti

Prebacivanje niza u broj java. Pretvaranje Java nizova u druge vrste vrijednosti

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

U Javi su moguće konverzije između cijelih brojeva i vrijednosti s pomičnim zarezom. Također možete pretvoriti vrijednosti cijelog broja i pomičnog zareza u vrijednosti char i obrnuto, jer svaki znak odgovara Unicode znamenki. Zapravo, Boolean tip je jedini primitivni tip u Javi koji se ne može pretvoriti u drugi primitivni tip. Osim toga, bilo koji drugi primitivni tip ne može se pretvoriti u Boolean.

U Javi postoje dvije vrste pretvorbe tipa: implicitno I eksplicitan.

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

  1. Obje vrste su kompatibilne
  2. Duljina vrsta cilja veća ili jednaka duljini izvornog tipa

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

Također postoje dvije vrste transformacija:

  1. Proširenje pretvorbe
  2. Sužavanje konverzije

Širenje transformacije ( proširenje pretvorbe) događa se ako se vrijednost jednog tipa pretvori u širi tip, s većim rasponom prihvatljive vrijednosti. Java automatski izvodi proširene pretvorbe, na primjer, ako dodijelite int literal dvostrukoj varijabli ili vrijednost char varijable int varijabli. Implicitna konverzija uvijek ima vrstu proširenja.

Ali ovo može imati svoje male grablje. Na primjer, ako se int vrijednost pretvara u float vrijednost. A vrijednost int u binarnom prikazu veća je 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 ne stanu u 23 bita float mantise bit će odbačene, pa iako će redoslijed broja biti sačuvan, preciznost će biti izgubljena. Isto vrijedi i za obraćenje dugog tipa tipkati dvostruko.

Proširenje pretvorbe Java tipova također se može prikazati na sljedeći način:

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

Vrijedi malo objasniti zašto se npr. tip byte ne pretvara automatski (ne eksplicitno) u tip char, iako tip byte ima širinu od 8 bita, a char 16, isto vrijedi i za konverziju kratki tip za char. To se događa jer su byte i short tipovi podataka s predznakom, a char je bez predznaka. Stoga u u ovom slučaju Morate koristiti eksplicitno pretvaranje tipa jer trebate eksplicitno reći kompajleru da znate što želite i kako će se rukovati znakom bita byte i short tipova prilikom pretvaranja u char.

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

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

Sužavanje transformacije ( sužavanje pretvorbe) događa se kada se vrijednost pretvori u vrijednost tipa čiji raspon nije širi od izvornog. Pretvorbe sužavanja nisu uvijek sigurne: na primjer, pretvaranje vrijednosti cijelog broja 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 se podaci mogu izgubiti tijekom sužavanja konverzije, Java kompilator odbija svaku takvu konverziju, čak i ako vrijednost koja se pretvara spada unutar užeg raspona navedenog tipa:

int ja = 13 ;
bajt b = ja ; // Prevodilac neće dopustiti ovaj izraz

Jedina iznimka od pravila je kada se cijeli literal (vrijednost int) dodjeljuje varijabli byte ili short ako literal odgovara rasponu varijable.

Konverzija sužavanja uvijek je eksplicitna konverzija tipa.

Eksplicitna konverzija primitivni tipovi

Operator eksplicitne konverzije tipa, točnije, pretvaranja tipa je okrugle zagrade, unutar kojeg je naznačena vrsta u koju se pretvara - (tip). Na primjer:

int ja = 13 ;
bajt b = ( bajt ) ja ; // Prisilna pretvorba iz int u bajt
ja = ( int ) 13.456 ; // Prisilna konverzija dvostrukog literala u int 13

Najčešće se koristi primitivni tip lijevanja za pretvaranje vrijednosti pomičnog zareza u cijele brojeve. pri čemu frakcija vrijednosti s pomičnim zarezom jednostavno se odbacuju(odnosno, vrijednost s pomičnim zarezom zaokružuje se prema nuli, a ne prema najbližem cijelom broju). U srži uzima se samo cjelobrojni dio pravi tip i već je pretvoren u ciljni cjelobrojni tip.

Prilikom donošenja većeg kapaciteta cijeli tip onom manjeg kapaciteta, najvažniji bitovi se jednostavno odbacuju. U biti, ovo je ekvivalentno operaciji dijeljenja modulo vrijednosti koja se smanjuje za raspon ciljanog tipa (na primjer, za tip bajta to je 256).

Prevelik razlomački broj kada se pretvori u cijeli broj, postaje MAX_VALUE ili MIN_VALUE.

Prevelik dvostruko kada se dovede do plutati pretvara se u Float.POSITIVE_INFINITY ili Float.NEGATIVE_INFINITY.

Donja tablica 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 da konverzija nije moguća. Pismo Y znači proširenu transformaciju koja se izvodi automatski. Pismo S znači sužavanje transformacije koja zahtijeva eksplicitno pretvaranje. Konačno, Y* znači transformaciju automatskog proširenja, tijekom koje vrijednost može izgubiti neke od svojih najmanje značajnih znamenki. To se može dogoditi kada pretvarate int ili long u float ili double. Tipovi s pomičnim zarezom imaju veći raspon od cjelobrojnih tipova, tako da int ili long mogu biti predstavljeni s float ili double. Međutim, tipovi s pomičnim zarezom su aproksimacije brojeva i ne moraju uvijek sadržavati onoliko značajnih znamenki u mantisi kao cjelobrojni tipovi.

Automatsko proširenje tipa u izrazima

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

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

Implicitno pretvaranje tipa u mješovite izraze dodjele

Iako ovaj odjeljak a odnosi se na implicitnu konverziju (casting) tipova, ovdje smo dali njegovo objašnjenje, jer u ovom slučaju radi i automatsko proširenje tipa u izrazima, a zatim implicitna cast vrste. Ovo je corps de ballet. Mislim da će primjer u nastavku sve razjasniti. Baš kao u prethodnom objašnjenju, znak @ znači bilo koji valjani operator, na primjer + , , * , / i tako dalje.

Ovo vrijedi objasniti jednostavnim primjerom:

bajt b2 = 50 ;
b2 = b2 * 2 ; // neće kompilirati
b2 *= 2 ; //kompilira, iako je ekvivalent b2 = b2 * 2

Drugi redak naveden u primjeru se ne kompajlira zbog automatskog proširenja tipa u izrazima, budući da je izraz b2*2 tipa int, jer dolazi do automatskog proširenja tipa (cjelobrojni literali u izrazu su uvijek int). Treći redak će se lako prevesti, budući da će implicitno pretvaranje tipa u izraz kombinirane dodjele raditi u njemu.

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

Boxing i unboxing je također prilično velika tema, ali je prilično jednostavna.

U srži boxing i unboxing su pretvorbe iz primitivnih tipova u objekte omotače i natrag.

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

Klase omotača spomenute su u tablicama pri analizi svakog od primitivnih tipova. Ali tada je to bio samo spomen u tablici.

Dakle, za svaki primitivni tip postoji njegov stariji brat, a on 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čki proračuni, 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.

Dat ću vam 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 nije strašno, samo vežite čvor kao uspomenu.

U ovu lekciju reći ćemo vam o maloj glavobolji za programere - prilagodbi tipa. Što je lijevanje tipa? Ovo je bilo koja konverzija vrste podataka.
Na primjer:

Int b = 3;
dvostruko a = 1,0 * b;//pretvorba tipa
a = (double)b;//pretvorba tipa

Dakle, možete vidjeti dva načina za promjenu vrste:

  • Izvođenje nekih operacija na objektu
  • Eksplicitna konverzija

Na koje se vrste može svesti? Možete prenijeti na tipove podataka koji su u istoj hijerarhiji. Recimo da cijeli broj možete pretvoriti u realan broj i obrnuto. Možete pretvoriti klasu učenika u klasu korisnika i tako dalje. Očito, pretvaranje niza u broj je beskorisno, budući da su to različiti objekti. U ovom slučaju obično se koriste posebne operacije.
Više ili manje iskusni korisnici Može se pojaviti sljedeće pitanje:

Int b = 3;
dvostruko a = b;//pretvorba tipa 1
b = (int) a;//pretvorba tipa 2

Zašto se tipu podataka double može dodijeliti tip podataka int, a prevodilac neće generirati pogrešku, ali da bi se tip podataka pretvorio u int tip mora biti eksplicitno naveden? Ispada da se sigurne konverzije, na primjer iz int u double ili iz podređenog u nadređenog, nazivaju proširivanjem, tj. dopuštamo tipu podataka s nižim mogućnostima da se proširi, na primjer integer tipu podataka, dopuštamo da postane stvaran, proširujući njegov opseg. Konverzija se naziva proširivanjem ako tip podataka na koji pretvaramo uključuje tip podataka na koji želimo pretvarati za osnovne tipove.
Pretvorbe sužavanja uvijek su povezane s nekim gubitkom informacija, na primjer, kod pretvorbe iz double u int gubimo sve vrijednosti nakon decimalne točke, što uzrokuje zabrinutost za računalo i samo eksplicitna naznaka vrsta podataka može ga uvjeriti da ovu transformaciju radimo zdravog razuma i čvrstog pamćenja.
Pogledajmo ponovno primjer s oblicima:

Oblik javne klase (
}
javna klasa Square extends Shape (
}
trg trg;
Oblik oblika = kvadrat;//proširujuća transformacija
kvadrat = oblik;//sužavanje transformacije

Čini se da se, pretvarajući se iz sina u roditelja, mi, naprotiv, sužavamo, a ne širimo, što je razlog? A razlog je taj što zapravo klasa Square sadrži sve informacije klase Shape i kada se transformiramo iz sina u oca, gubimo samo informacije specifične za sina, koje su u ovaj trenutak možda nije važno, ali kod transformacije iz oblika u kvadrat možemo doći u situaciju da jednostavno nemamo podatke potrebne za rad klase, na primjer, nemamo veličinu kvadrata, ako govorimo o primjer iznad.
I na kraju lekcije, pogledajmo operator instanceof, on vraća true ako objekt ima navedeni tip:

If(new Square() instanceof Shape)(//false

Java je strogo tipiziran programski jezik, što znači da svaki izraz i svaka varijabla ima striktno određena vrsta već u trenutku sastavljanja.
Vrste duhova
Java nudi sedam vrsta castova:

  • Identičan (identitet);

  • primitivno širenje;

  • Sužavanje primitivno;

  • Referenca za proširenje tipa objekta;

  • Sužavanje reference;

  • Pretvori u niz;

  • Zabranjene transformacije (zabranjene);
Pogledajmo ih zasebno.
Transformacija identiteta
Najjednostavnija je transformacija identiteta. U Javi, pretvaranje izraza bilo kojeg tipa u točno isti tip uvijek je važeće i uspješno.
Ovo je važno za mogućnost ustvrditi s teorijske točke gledišta da bilo koji tip u Javi može sudjelovati u pretvorbi, barem u pretvorbi identiteta.
Pretvorba primitivnog tipa (širenje i skupljanje)
Za jednostavne vrste ekspanzija znači da dolazi do prijelaza s manje prostranog tipa na veći. Na primjer, od tipa bajta (dug 1 bajt) do tipa int (dug 4 bajta). Takve transformacije su sigurne u smislu da novi tip uvijek zajamčeno sadrži sve podatke koji su bili pohranjeni u starom tipu, te stoga nema gubitka podataka. Zato ga prevodilac implementira sam, neprimijećen od strane programera:

bajt b=3;
int a=b;

Sljedećih 19 transformacija su ekspanzijske:

  • Od bajta do kratkog, int, dugog, float, dvostrukog

  • Od short do int, long, float, double

  • Od char do int, long, float, double

  • Od int do long, float, double

  • Od dugog do plutajućeg, dvostrukog

  • Od float do double
Imajte na umu da ne možete pretvoriti u char iz tipova manjih od ili jednake dužine(byte, short) ili, obrnuto, kratko od char bez gubitka podataka. To je zbog činjenice da je char, za razliku od ostalih tipova cjelobrojnih brojeva, predznačen.
Međutim, treba imati na umu da čak i uz proširenje podaci mogu biti iskrivljeni. Ovo je bacanje int vrijednosti na tip plovka i pretvaranje dugih vrijednosti u float ili double. Iako ove frakcijske vrste mogu primiti mnogo velike brojke, od odgovarajućih cijelih brojeva, ali imaju manje značajnih znamenki.
Na primjer:

dug a = 111111111111L;
plovak f=a;
a=(dugo)f; // () ovo je upravo operacija pretvorbe tipa
System.out.println(a); //rezultat 111111110656

Imajte na umu da sužavanje znači prijelaz s većeg tipa na manji. Kod ove konverzije postoji rizik od gubitka podataka. Na primjer, ako je int broj bio veći od 127, tada će se prilikom pretvaranja u bajt izgubiti vrijednosti bitova viših od osmog. U Javi se takva konverzija mora izvršiti eksplicitno, tj. Programer u kodu mora izričito naznačiti da namjerava izvršiti takvu konverziju i da je spreman izgubiti podatke.
Sljedeće 23 transformacije se sužavaju:

  • Od bajta do znaka

  • Od kratkog do bajta, char

  • Od char do byte, kratko

  • Od int do byte, short, char

  • Od long do byte, short, char, int

  • Od float do byte, short, char, int, long

  • Od double do byte, short, char, int, long, float
Kada se cjelobrojni tip sužava na uži cjelobrojni tip, svi bitovi višeg reda koji ne spadaju u novi tip jednostavno se odbacuju. Ne izvode se zaokruživanja niti druge radnje da bi se dobio točniji rezultat:

System.out.println((bajt)383);
System.out.println((byte)384);
System.out.println((bajt)-384);

Rezultat će biti:

127
-128
-128
Vidljivo je da bit predznaka nije imao nikakvog učinka pri sužavanju, jer je jednostavno odbačen - rezultat dovođenja recipročnih brojeva (384, -384) pokazao se istim. Posljedično, može se izgubiti ne samo točna apsolutna vrijednost, već i predznak veličine.
Ovo vrijedi i za char:

char c=4000;
System.out.println((kratko)c);

Proizlaziti:

-25536
Pretvorba referentnog tipa (širenje i skupljanje)
Pretvorba tipa objekta najbolje se ilustrira pomoću stabla nasljeđivanja. Pogledajmo mali primjer nasljeđivanja:

roditelj klase(
int x;
}

klasa ChildY proširuje roditelja (
int y;
}

klasa ChildZ proširuje roditelja (
int z;
}

Svaka klasa deklarira polje s jedinstvenim imenom. Ovo polje ćemo smatrati primjerom skupa jedinstvenih svojstava svojstvenih nekom tipu objekta.
Objekti klase Parent imaju samo jedno polje x, što znači da se samo reference tipa Parent mogu odnositi na takve objekte. Objekti klase ChildY imaju polje y i polje x, naslijeđeno od klase Roditelj. Stoga se na takve objekte može ukazivati ​​referencama tipa ChildY ili Parent. Primjer:

Roditelj p = novo dijeteY();

Imajte na umu da takva referenca p može pristupiti samo x polju kreiranog objekta. Polje y nije dostupno jer kompajler, kada provjerava valjanost izraza p.y, ne može predvidjeti da će referenca p ukazivati ​​na objekt tipa ChildY tijekom izvođenja. Ona samo analizira tip same varijable i deklarirana je kao roditelj, ali ova klasa nema polje y, što će uzrokovati pogrešku kompilacije.
Slično, objekti klase ChildZ imaju polje z i polje x izvedeno iz klase Parent. To znači da se na takve objekte može ukazivati ​​vezama poput ChildZ i Parent.
Dakle, reference tipa Parent mogu ukazivati ​​na objekt bilo kojeg od tri razmatrana tipa, ali reference tipa ChildY i ChildZ mogu ukazivati ​​samo na objekte potpuno istog tipa. Sada možemo prijeći na pretvaranje referentnih tipova na temelju ovog stabla nasljeđivanja.
Proširenje znači prelazak s specifičnije vrste na manje specifičnu vrstu, tj. prijelaz s djece na roditelje. Slično kao i kod primitivnih tipova, ovu tranziciju po potrebi radi sam JVM i “nevidljiva” je programeru, odnosno ne zahtijeva nikakve posebne konverzije.

Roditelj p1=novo dijeteY();
Roditelj p2=novo dijeteZ();

Na obje linije varijable tipa Roditelju se dodjeljuje vrijednost drugog tipa, što znači da dolazi do konverzije. Budući da je ovo proširenje, radi se automatski i uvijek je uspješno.
Treba napomenuti da se tijekom takve transformacije ništa ne događa samom objektu. Iako, primjerice, polje y klase ChildY više nije dostupno, to ne znači da ga više nema. Tako značajna promjena na objektu nije moguća. Izveden je iz klase ChildY i zadržava sva svoja svojstva. Promijenjen je samo tip poveznice preko koje se pristupa objektu.
Obrnuti prijelaz, odnosno pomicanje niz stablo nasljeđivanja do nasljednika, je sužavanje. Na primjer, u ovom slučaju, prelazak s reference tipa Parent, koja se može odnositi na objekte triju klasa, na referencu tipa ChildY, koja se može odnositi samo na jednu od tri klase, očito je sužavanje. Takav prijelaz možda neće biti moguć. Ako se referenca tipa Parent odnosi na objekt tipa Parent ili ChildZ, tada prijelaz na ChildY nije moguć, jer u oba slučaja objekt nema polje y, koje je deklarirano u klasi ChildY. Stoga projektant prilikom sužavanja treba izričito naznačiti da je potrebno pokušati takvu transformaciju. JVM će provjeriti je li prijelaz točan tijekom izvođenja. Ukoliko bude moguće izvršit će se prenamjena. Ako nije, pojavit će se pogreška (obično ClassCastException).

Roditelj p=novo dijeteY();
DijeteY cy = (DijeteY)p; //pravo
Roditelj p2=novo dijeteZ();
DijeteY cy2 = (DijeteY)p2; //pogreška

Kako biste provjerili je li željeni prijelaz moguć, možete koristiti operator instanceof:

Roditelj p=novo dijeteY();
if (p instanca ChildY) (
DijeteY cy = (DijeteY)p;
}

Roditelj p2=novo dijeteZ();
if (p2 instanca ChildY) (
DijeteY cy = (DijeteY)p2;
}

Roditelj p3=novi roditelj();
if (p3 instanca ChildY) (
DijeteY cy = (DijeteY)p3;
}

U u ovom primjeru neće doći do grešaka. Prva transformacija je moguća i bit će ostvarena. U drugom i trećem slučaju, uvjeti if naredbi neće raditi i stoga neće biti netočnog prijelaza.
Pretvorba u niz
Bilo koji tip se može pretvoriti u niz, tj. kopirati klasa String. Ova transformacija je izuzetna po tome što pokriva apsolutno sve vrste.
Različiti tipovi se pretvaraju u niz na sljedeći način:

  • Numerički tipovi se pišu u tekstualni oblik bez gubitka točnosti prikaza. Prvo se generira instanca odgovarajuće klase "omotač" na temelju primitivne vrijednosti, a zatim se poziva njena metoda toString(). Ali budući da su te radnje nevidljive izvana, JVM ih optimizira i pretvara primitivne vrijednosti izravno u tekst.

  • Booleove vrijednosti pretvaraju se u niz "true" ili "false" ovisno o vrijednosti.

  • Za vrijednosti objekta poziva se metoda toString(). Ako metoda vrati null, rezultat će biti niz "null".

  • Za vrijednost null generira se niz "null".
Zabranjene pretvorbe
Nisu dopušteni svi prijelazi između proizvoljnih tipova. Na primjer, zabranjene pretvorbe uključuju: prijelaze iz bilo kojeg referentnog tipa u primitivni tip i obrnuto (osim za pretvorbu u niz), booleov se može pretvoriti samo u ovaj tip ili u niz. Osim toga, nemoguće je međusobno dovesti klase smještene na susjednim granama stabla nasljeđivanja. U primjeru korištenom za ilustraciju referentnih tipova, prijelaz od ChildY do ChildZ je zabranjen.
Ovaj popis zabranjenih transformacija tu ne završava. Prilično je širok, a istodobno su sve mogućnosti prilično očite, pa se o njima neće detaljno raspravljati. Tko želi može dobiti pune informacije iz specifikacije.
Naravno, pokušaj nelegalne pretvorbe uzrokovat će pogrešku.

Korištenje odljeva
Situacije za korištenje pretvorbe tipa mogu se grupirati na sljedeći način:

  • Dodjeljivanje vrijednosti varijablama (dodjela). Nisu svi prijelazi dopušteni tijekom ove transformacije - ograničenja su odabrana na takav način da ne može doći do iznimke.

  • Poziv metode. Ova se konverzija primjenjuje na argumente pozvane metode ili konstruktora. Takva postava nikada ne proizvodi greške. Casting se također provodi kada se vrati vrijednost metode.

  • Eksplicitni casting. U ovom slučaju, eksplicitno je naznačeno u koji tip treba pretvoriti izvornu vrijednost.

  • Operator ulančavanja pretvara u niz svojih argumenata.

  • Numeričko proširenje. Numeričke operacije može zahtijevati promjenu vrste argumenata. Ova konverzija ima poseban naziv - proširena, budući da izbor ciljne vrste može ovisiti ne samo o izvornoj vrijednosti, već io drugom argumentu operacije.
Zadatak #8
Dodajte svom projektu korištenje kastinga za svoju hijerarhiju klasa.

Prethodni govornik opisao je dosta u potpunosti pretvorba prema dolje, ali suština (po mom mišljenju) zahtijeva dodatno objašnjenje, jer je pitanje vrlo popularno i zanimljivo.

Kako funkcionira eksplicitno pretvaranje tipa

Vaš primjer pokazuje transformaciju prema gore ( Upcasting):

List coll = new ArrayList();

Na ruski se prevodi na sljedeći način: stvorite vranu, poput ptice. Stvorite dinamički niz, poput lista. U većini situacija, konverzija prema gore potpuno je nepotrebna.
Međutim, odabir tipa funkcionira na intervjuima kada vam se postavljaju pitanja o nasljeđivanju. Na primjer, web stranica quizful.net općenito sadrži mnogo pitanja o pretvorbi tipa. Stoga ću objasniti značajke koje poznajem.

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

1. Veza se može usmjeriti na bilo kojeg roditelja. Čak i jako davno. To jest, možete cast referencu coll čak i na tip Object. Kompajler će preskočiti sve reference na roditeljsku klasu, ili roditelj-roditelj, ili roditelj-roditelj...roditelj

2. Prilikom pristupa polju uvijek se vraća polje reference, a ne polje objekta. Ako nema takvog polja u referentnoj klasi, doći će do pogreške kompilacije.

Klasa A( int x = 2; //Nadređeno polje) Klasa B proširuje A ( int x = 3; //Polje koje bi trebalo preklapati nadređeno int y = 5; //Polje koje nije u nadređenoj klasi. ) Klasa Test ( public static void main(String args) ( A ab = new 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š kompajler će reći da niste u pravu, jer ne vidi takvo polje u poveznici (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 se vratiti metoda objekta. Ali kada se pristupa statičkoj metodi, vraća referentnu metodu.

Klasa D( public void doSome())( //Nestatična metoda System.out.println("Nonstatic doSome from D"); ) public static void Action())( //Statična metoda System.out.println("static Action from 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čni doSome iz Okeya

statična akcija iz D

Rješenje je jednostavno, nestatična metoda je metoda objekta, statična metoda je metoda klase. Kada pozivamo nestatičku metodu, prevodilac razumije ovo: leti kao vrana. Kada to zovemo statično - doslovno, leti kao ptica.

4. Ako postoji poziv metode koja je opisana u klasi objekta, ali nije opisana u referentnoj klasi, pojavit će se pogreška kompilacije. Budući da 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 objekta (kada je kreiran novom naredbom) radi isto kao da date vezu na svoju klasu.

Ovaj članak:

  • napisao tim. Nadamo se da će vam biti od koristi. Sretno čitanje!
  • ovo je jedan od naših članaka

Pretvorba tipa je tema koja se može činiti zastrašujućom za one koji su tek upoznati s Java programiranjem. Međutim, uvjeravamo vas da je sve zapravo jednostavno. Glavno je razumjeti koji zakoni upravljaju interakcijom između varijabli i zapamtite to kada pišete programe. Dakle, idemo shvatiti.

U Javi postoje 2 vrste transformacija - slika će vam pomoći:

Podsjetimo se da se cijeli "Java svemir" sastoji od:

  • primitivni tipovi (byte, short, int, long, char, float, double, boolean)
  • objekti

U ovom članku mi:

  • razmotrite pretvorbu tipa za primitivne tipove varijabli
  • pretvorba objekata (String, Scanner, itd.) nije razmatrana u ovom članku, budući da se s objektima događa posebna "magija" - ovo je tema za poseban članak.
Automatska konverzija

Pa, pokušajmo shvatiti što je "automatska pretvorba".

Zapamtite, kada smo gledali tipove varijabli (u članku), rekli smo to varijabla je neka vrsta "spremnika" , koji može pohraniti vrijednost za kasniju upotrebu u programu. Također smo govorili o činjenici da svaka vrsta varijable ima svoj raspon valjanih vrijednosti i količinu memorije koju zauzima. Evo znaka gdje je sve to ispisano:

Dakle, ovo je ono do čega zapravo dolazimo. Osim toga, nije samo da ste dobili raspone prihvatljivih vrijednosti i količinu zauzete memorije :)

Usporedimo npr.

1. bajt i kratki. byte ima manji raspon važećih vrijednosti nego short. Odnosno, byte je kao manja kutija, a short je veća kutija. A to znači možemo staviti bajt u kratki.

2. bajt i int. byte ima manji raspon valjanih vrijednosti od int. Odnosno, byte je poput manje kutije, a int je poput veće kutije. A to znači možemo staviti bajt u int.

3. int i dugi. int ima manji raspon valjanih vrijednosti nego long. Odnosno, int je kao manja kutija, a long je kao veća kutija. A to znači možemo staviti u dugo.

Ovo je primjer automatske pretvorbe. To se shematski može prikazati u obliku slike poput ove:

Pogledajmo kako to funkcionira u praksi.

Primjer br. 1

Kod br. 1 - ako pokrenete ovaj kod na svom računalu,

klasa Test ( public static void main(String args) ( byte a = 15; byte b = a; System.out.println(b); ) )

razredni test (

bajt a = 15;

bajt b = a;

Kod br. 2 - ako pokrenete ovaj kod na svom računalu, na konzoli će se prikazati broj 15

klasa Test ( public static void main(String args) ( byte a = 15; int b = a; System.out.println(b); ) )

razredni test (

public static void main (String args) (

bajt a = 15;

int b = a;

Sustav. van . println(b);

Eeyore? Misliš li to puta je isti broj izbačen na konzolu, a kod br. 1 razlikuje se od koda br. 2 samo po vrsti varijable b , onda nema razlike među njima? E to nije istina.

Kod broj 2 sadrži automatskipretvorba tipa , ali kod br. 1 - ne:

Iako je broj u načelu isti, sada je u b O veći spremnik koji zauzima više prostora na disku. U ovom slučaju, JVM izvodi automatske pretvorbe za tebe. Ona to zna int više od bajt .

Cast

Druga je stvar ako nešto pokušavate pretočiti iz veće posude u manju.

Možda znate da veći spremnik sadrži nešto što može stati u mali - ali JVM ne zna za to i pokušava vas zaštititi od pogrešaka.

Stoga morate “jasno reći” da je situacija pod kontrolom:

klasa Test ( public static void main(String args) ( int a=0; long b=15; a = (int) b; ) )

razredni test (

public static void main (String args) (

int a = 0;

dug b = 15 ;

a = (int) b;

Ovdje smo dodali (int) prije b. Ako varijabla a bio je, na primjer, kao bajt, u zagradi bi bilo (bajt) . Opća formula izgleda ovako:

Ona kaže "napravite (više) značenja b varijabla tipa koji mi treba (cilj) int ".

Ako je nešto pošlo po zlu.

Prije toga smo situacijama pristupali pretpostavljajući da točno znamo što radimo. Ali što ako pokušate staviti nešto u spremnik što tamo ne stane?

Ispada da će u spremniku ostati samo ono što tamo "stane". Na primjer, za brojeve s pomičnim zarezom razlomački dio bit će "odsječen":

//primjer 1 klase Test ( public static void main(String args) ( double a=11.2345; int b=(int)a; System.out.println(b); // konzola će prikazati broj 11 ) )

//primjer 1

razredni test (

public static void main (String args) (

dvostruko a = 11,2345;

int b = (int ) a ;

Sustav. van . println(b); // konzola će prikazati broj 11

Moramo zapamtiti da je razlomački dio nije zaobljena, A odbačena.

Što se događa ako pokušamo postaviti broj koji je izvan dopuštenog raspona? Na primjer, ako stavite broj 128 u bajt (raspon bajtova od -128 do 127)? Mislite li da ćemo dobiti 1? Ne. Dobivamo -128:

class Test ( public static void main(String args) ( double a=128; byte b=(byte)a; System.out.println(b); //u konzoli ćemo vidjeti -128) )

Vrijednost varijable s takvom transformacijom može se izračunati, ali cilj programera je izbjeći situaciju u kojoj vrijednost prelazi dopuštene granice, jer to može dovesti do kvar programa.

Zadaci:
  1. Dosljedno zapišite u kompajler međusobne pretvorbe svih primitivnih tipova, uključujući char i tipove. Napravite ovakvu tablicu:
bajt kratak char int dugo plutati dvostruko Booleov
bajt
kratak
char
int
dugo
Plutati
dvostruko
Booleov

Na raskrižju napišite: a - ako se pretvorba događa automatski, na - ako trebate koristiti eksplicitnu pretvorbu, x - ako je pretvorba nemoguća.

* poziva se pretvaranje tipa u samoga sebe identičan– nije ga potrebno registrirati

  1. Ponovno pogledajte koje je veličine svaki primitivni tip. Pokušajte napraviti dijagram toka koji prikazuje koje vrste kamo idu. Nacrtajte strelice s oznakom "transformacija širenja" i "transformacija sužavanja".
Pitanja

Tijekom intervjua za poziciju Junior Java Developer, mogli biste biti upitani:

Što znate o pretvaranju primitivnih tipova podataka, postoji li gubitak podataka, je li moguće pretvoriti Boolean tip?

Pokušajte odgovoriti na pitanje.

Ukratko:
  • Ako sadržaj manjeg spremnika "stavite" u veći spremnik, konverzija se događa automatski i ne bi se smjele pojaviti greške.
  • Ako postoji potreba za stavljanjem "vrijednosti iz većeg spremnika u manji", morate biti oprezni i koristiti eksplicitno pretvaranje tipa.
  • Prilikom pretvaranja float ili double u cjelobrojne tipove, razlomački dio se ne zaokružuje, već se jednostavno odbacuje.
  • Tip boolean ne može se pretvoriti ni u jedan tip.
  • Tip char pretvara se u numeričke tipove, poput znakovnog koda u UNICODE sustavu.
  • Ako je broj veći od spremnika, rezultat će biti nepredvidiv.

Ovaj članak opisuje samo dio materijala na temu lijevanja tipa. Tu su i pretvaranja tipa objekta, pretvaranja u niz (uostalom, sve se može napisati u nizu, zar ne?) i automatsko unapređenje tipa u izrazima.

Nadamo se da vam je naš članak bio koristan. Također postoji mogućnost upisa na naše Java tečajeve u Kijevu. Podučavamo od nule. Detaljne informacije Možete ga pronaći na našoj web stranici.


Najbolji članci na temu