Casting betyr å "støpe (om)" og handler om å endre typen til et uttrykk. Syntaksen er (<type>) <uttrykk>, f.eks. (String) object, altså en type i parentes foran et annet uttrykk. En har ofte parenteser utenpå der igjen.
Det finnes to varianter av casting, casting av tall-typer og casting av objekt-typer.
Casting av tall-typer
Ved casting av talltyper som int og double så ber man om konvertering fra en type til en annen, f.eks. double div = (double) 2 / 3. Uten casten, altså (double), ville dette blitt tolket som heltallsdivisjon og gitt svaret 0. Men med casten så blir 2 først konvertert til 2.0 av typen double, som så deles på 3 til 0.66666666... Ved casting av tall kan en miste informasjon/presisjon, f.eks. vil int div2 = (int) div konvertere div sin verdi (0.66666...) til en int og da fjernes desimalene, slik at svaret blir 0.
Casting av objekt-typer
Ved casting av objekt-typer, så konverteres ikke objektet, men referansen, i den forstand at Java aksepterer at (typen til) en referanse er til en annen type enn uttrykket selv har. F.eks.
Object o = "1234"; String s = ((String) o).substring(1);
Her vil o referere til en String, men siden o er deklarert som Object, så kan en ikke kalle String-metoder som substring. Derfor har man en cast foran/rundt o før man kaller substring. o refererer hele tiden til det samme objektet, men Java aksepterer på den andre linja at o betraktes som en String og ikke bare som en Object. Hvis det viser seg at o ikke er en String, så utløses et unntak av typen ClassCastException. For å unngå dette så kombineres ofte casting med en instanceof-sjekk, f.eks.
if (o instanceof String) { String s = ((String) o).substring(1); }
Casting er vanligst når en bruker arv, hvor en variabel er deklarert til å være en supertype og en ønsker å kalle en metode deklarert i en subklasse, hvis objektet er av subklassen, selvsagt. Dette kalles også "down-casting" fordi en caster nedover i arvingshierarkiet. Det motsatte er "up-casting", dvs. casting oppover i hierarkiet, f.eks. (Object) s, når s er deklarert som String. Dette kan virke litt poengløst, siden en jo kan kalle Object sin metoder, f.eks. equals og toString, på en String, men det er nyttig for å "velge" riktig metode når en har brukt overloading:
// brukes når argumentet har typen String void something(String s) { ... } // brukes når argumentet har typen Object void something(Object o) { ... } void somethingElse(String s) { something(s); // kaller den øverste something, siden uttrykket s har typen String something((Object) s); // kaller den nederste something, siden uttrykket (Object) s har typen Object }