Java - Típuskonverziók
vitafórum(0)
szerző: Crystaldátum: 2009-07-28
Kategóriák:
Java/Alapok
A Java erősen típusos nyelv, így a sok más nyelvben megtalálható automatikus típuskonverzió nem működik, ezt programozottan kell megtennünk. Ebben a tutorialban leírom, hogy ez pontosan hogy működik.
Java-ban a típusokat alapvetően két csoportba oszthatjuk: primitív típusok és objektumok. Először a primitív típusok közti lehetséges konverziókat nézzük át, majd a primitívek és csomagoló osztályaik közti kapcsolatot, végül az objektum-objektum konverziót.
Primitív típusok
Ismétlésképp nézzük át a primitív típusokat:
Egészek:
* byte: 8 bites, értékkészlete: -128 ... +127
* short: 16 bites, értékkészlete: -32.768 ... +32.767
* int: 32 bites, értékkészlete: -2.147.483.648 ... +2 147.483.647
* long: -9.223.372.036,854.775.808 ... 9,223,372,036,854,775,807
Az egész típusok nagyság szerint felfelé automatikusan konvertálódnak, de lefelé fordítási hibát kapunk. Tehát:
short s = 10;
long l = 10;
l = s; //fordítási hiba
s = l; //lefordul
Lebegőpontos típusok:
* float: 32 bites lebegőpontos szám
* double 64 bites lebegőpontos szám
Ezekre ugyanaz igaz, mint az egész típusokra: float érték kovertálódik double-re, fordítva pedig fordítási hibát kapunk. Bármelyik egész típus konvertálható lebegőpontos típussá.
Ezen kívül van még két primitív típus: a boolean és a char. A boolean nem konvertálható más típusra, a char pedig byte-on kívül bármilyen numerikus típusra.
Autoboxing
A primitív típusokhoz tartoznak úgynevezett csomagoló osztályok. Tehát int - Integer, char - Character stb. Ezek között automatikus a konverzió, viszont a csomagoló osztályok nem konvertálhatóak automatikusan egymásba. Pl.:
Integer iO = 10;
int i = iO;
i = 20;
iO = i;
Long lO = iO; //fordítási hiba
Kézzel úgy állíthatunk elő csomagoló objektumot egy primitív értéknek, hogy konstruktor-paraméterként átadjuk azt. Csomagoló objektumból a megfelelő metódus hívásával kapjuk vissza a primitív értéket. Pl.:
int i = 10;
Integer iO = new Integer(i);
int i2 = iO.intValue();
Tulajdonképp az autoboxing megvalósítása is úgy tűnik, hogy a fordító ilyen utasításokat helyez el a kódban ott, ahol ez szükséges.
Objektumból objektumba
Mint tudjuk, Java-ban minden nem primitív változó egy objektum-referencia. Tehát a változók nem a konkrét objektumot reprezentálják, hanem egy hivatkozás (referenciát, mutatót) az objektumra. Ezt figyelembe véve vezessünk be két fogalmat a téma áttekintéséhez:
* deklarált típus: az a típus, mellyel az objektum-referenciát deklaráljuk
* aktuális típus: annak az objektumnak a típusa, melyre az objektum-referencia aktuálisan mutat.
Nézzünk egy példát:
Object var = new Integer(2);
Tehát itt az var változó deklarált típusa az Object és az aktuális típusa az Integer.
Tehát a lehetséges konverziók:
Minden változó (objektum-referencia) aktuális típusa lehet olyan típus, mely a változó deklarált típusának származtatott osztálya.
Ha a deklarált típus interfész, akkor az aktuális típusnak implementálnia kell a deklarált típust.
Ha aktuális típusnak a deklarált típus egyik ősosztályát szeretnénk adni, akkor manuálisan kell elvégeznünk a típuskonverziót (cast-olás).
A következő három állítás erejéig vezessük be a megfelelőség fogalmát: egy B típus A-nak megfelelő, ha B származtatott osztálya vagy ősosztálya A-nak, vagy ha A egy interfész, akkor B implementálja A-t.
Ha aktuális típusnak olyan típust szeretnénk adni, mely nem megfelelő a deklarált típusnak, akkor fordítási hibát kapunk (inconvertible types).
Ha egy a változónak olyan b változó által hivatkozott objektumot szeretnénk hivatkozott értékül adni, melyre igaz, hogy b deklarált típusa megfelelő a típusának, de b aktuális típusára ez nem igaz, akkor futásidejű hibát, ClassCastException-t kapunk.
Az előzőhöz hasonlóan ha egy a tömb típusú változó egyik elemének olyan értéket szeretnénk adni, mely a tömb deklarált típusának megfelelő, de az aktuális típusának nem, akkor ArrayStoreException-t kapunk.
Példák:
Object o = new Integer();
CharSequence seq = new String("");
Integer i = (Integer) new Object(); //cast-olás
String str = (String) new Integer(); //fordítási hiba
Object o2 = str;
Integer i2 = (Integer) o2; //ClassCastException
Object[] oArr = new String[10];
oArr[0] = new Integer(2); //ArrayStoreException
Ebben a tutorialban a Java generikusának vonatkozó részét nem írtam le, ezt majd ott..
