Navigation


RSS: tutorialok Jelenleg 5 vendég és 0 tag van az oldalon.

Java - Típuskonverziók

szerző: Crystal
dá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..