Het type-conversiemechanisme in Java (type casting) stelt de programmeur in staat om expliciet of impliciet een waarde van het ene type naar het andere type om te zetten. Historisch gezien is deze eigenschap overgenomen van C en C++, maar in Java is deze beperkt om de typeveiligheid te vergroten en verborgen bugs te voorkomen die verband houden met overloop of dataverlies.
Probleem is de mogelijkheid van het ontstaan van een ClassCastException bij het converteren van referentietypes, evenals precisieverlies bij de conversie van primitieve types, bijvoorbeeld wanneer je van double naar int gaat. Er zijn logische fouten mogelijk bij het zogenaamde "downcasting" (converteren naar een subtype), als het exemplaar niet tot deze klasse behoort.
Oplossing bestaat uit een strikte scheiding:
Voorbeeldcode voor primitieve types:
int i = 100; long l = i; // impliciete conversie (int -> long) double d = l; // impliciet (long -> double) int i2 = (int) d; // expliciete conversie (verliest de fractie)
Voorbeeldcode voor referentietypes:
Object obj = "Hello"; // upcasting, impliciet String s = (String) obj; // downcasting, expliciet
Belangrijke kenmerken:
Kan de Java-compiler alle foute typeconversies voorkomen?
Antwoord: Nee, de compiler vangt alleen de voor de hand liggende fouten tijdens de compilatie. Als conversie mogelijk is in de typestructuur (bijvoorbeeld, Object -> String), maar in de variabele werkelijk een object van een incompatibel type aanwezig is, zal de fout zich alleen tijdens runtime manifesteren met een ClassCastException.
Erft Integer van Long, en kan ik schrijven Integer i = (Integer) someLong?
Antwoord: Nee, Integer en Long zijn onafhankelijke wrapperklassen, tussen hen kan geen downcasting plaatsvinden. Ze eren beide van Number, maar niet van elkaar. Conversie zoals (Integer) (Object) 1L; zal een ClassCastException veroorzaken.
Bij expliciete conversie van float naar int vindt er afronding van de fractie plaats?
Antwoord: Nee, de fractie wordt gewoon afgekapt zonder afronding:
float f = 3.99f; int i = (int) f; // i == 3, niet 4
Een ontwikkelaar ontvangt een Object-collectie en converteert elk element naar zijn type, maar controleert niet op instanceof. Het project valt consequent met een ClassCastException bij onjuiste gegevens.
Voordelen:
Nadelen:
Alle downcasting-operaties worden uitgevoerd binnen if (obj instanceof TargetType) met expliciete foutafhandeling. Voor collecties worden generics gebruikt.
Voordelen:
Nadelen: