W3docs

Type Casting in Java

Converti tra tipi primitivi in Java con la conversione implicita widening e il cast esplicito narrowing, evitando gli errori più comuni.

Il type casting consiste nel convertire un valore da un tipo a un altro. In Java esistono due varianti: le conversioni widening, che avvengono automaticamente e non perdono informazioni, e le conversioni narrowing, che richiedono un cast esplicito e possono comportare perdita di dati.

Conversione widening (implicita)

Una conversione widening sposta un valore in un tipo più grande. Il compilatore la gestisce automaticamente — non è necessaria alcuna sintassi speciale:

int i = 100;
long l = i;        // int → long (widening)
double d = l;      // long → double (widening)

System.out.println(i);   // 100
System.out.println(l);   // 100
System.out.println(d);   // 100.0

L'ordine standard delle conversioni widening è:

byte → short → int → long → float → double
              char ↗

(char si allarga a int e oltre, ma non a short o byte.)

La conversione widening non perde mai il range — un long rientra sempre nel range di un double, anche se double non può rappresentare ogni valore long in modo esatto. Attenzione a questo gap di rappresentazione esatta con valori estremi.

Cast narrowing (esplicito)

Una conversione narrowing sposta un valore in un tipo più piccolo. Java rifiuta di farlo implicitamente perché i dati possono andare persi. È necessario indicarlo esplicitamente con (targetType):

double d = 9.99;
int i = (int) d;   // explicit narrowing cast

System.out.println(i);   // 9 — the fractional part is dropped

Il cast tronca verso zero — non arrotonda.

Per i numeri interi, il cast mantiene solo i bit di ordine inferiore:

int big = 130;
byte b = (byte) big;
System.out.println(b);   // -126 — overflow wraps around

byte è a 8 bit, con range -128…127. I bit di 130 (10000010) vengono interpretati come -126 in complemento a due.

Un cast comune: divisione intera in numero reale

L'aritmetica puramente intera usa la divisione intera — 5 / 2 == 2, non 2.5. Per ottenere un risultato reale, è necessario eseguire il cast di almeno un operando prima della divisione:

int total = 5;
int count = 2;

double avgWrong = total / count;          // 2.0 — division is still integer
double avgRight = (double) total / count; // 2.5 — total widened first

Questo è il motivo più comune per cui si ricorre a un cast.

Cast di riferimento

La sintassi (Type) funziona anche sugli oggetti — sebbene in quel caso si tratti di un controllo a runtime, non di una conversione. Eseguire il cast di un riferimento equivale a dire "fidatevi, questo oggetto è di tipo X":

Object o = "Hello";
String s = (String) o;            // OK at runtime
System.out.println(s.length());   // 5

Object n = Integer.valueOf(7);
String bad = (String) n;          // throws ClassCastException at runtime

Per eseguire il cast di un riferimento in modo sicuro, è necessario verificare prima il tipo con instanceof:

Object o = "Hello";
if (o instanceof String) {
    String s = (String) o;        // guaranteed safe
    System.out.println(s.length());
}

Il pattern matching per instanceof (Java moderno) consente di effettuare il controllo e il cast in un unico passaggio. I cast di riferimento sono trattati in modo approfondito in OOP e Polimorfismo.

Un esempio funzionante

java— editable, runs on the server

Quando il compilatore "aiuta" — e quando no

Un caso sottile a cui prestare attenzione: l'aritmetica su byte, short o char viene automaticamente promossa a int prima dell'operazione. Il risultato è un int:

byte a = 10;
byte b = 20;
// byte sum = a + b;       // compile error: result is int
byte sum = (byte) (a + b);  // explicit cast needed

Questo sorprende tutti la prima volta. Si può memorizzare il risultato in un int, oppure riconvertire con un cast.

Regole pratiche

  • Widen liberamente — nessun cast necessario, nessuna perdita.
  • Narrow con un cast e un controllo — assicurarsi che il valore rientri effettivamente nel tipo.
  • Per la divisione in numeri reali tra interi, eseguire il cast di un operando a double.
  • Per i calcoli monetari, non usare double — usare BigDecimal per evitare errori di arrotondamento in virgola mobile binaria.

Cosa c'è dopo

Operatori Java — panoramica completa di tutti gli operatori disponibili nel linguaggio.

Pratica

Pratica
Quali conversioni richiedono un cast esplicito?
Quali conversioni richiedono un cast esplicito?
Was this page helpful?