Menu

Tipi di dati in Java: primitivi, tipi riferimento e valori predefiniti

I tipi di dati di Java spiegati: gli otto tipi primitivi, i tipi riferimento, i valori predefiniti, letterali e suffissi, l'overflow e quando usare ogni tipo numerico.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Due famiglie: primitivi e riferimenti

Ogni valore in Java ha un tipo, e quel tipo appartiene a una di due famiglie. I tipi primitivi contengono direttamente un valore grezzo: un numero, un singolo carattere o un vero/falso. I tipi riferimento contengono un riferimento (un puntatore) a un oggetto che si trova altrove in memoria: String, gli array e ogni classe definita da te o dalle librerie.

La distinzione conta perché i primitivi sono leggeri e vengono copiati per valore, mentre le variabili riferimento puntano a oggetti condivisi. Parti dagli otto primitivi: sono le fondamenta su cui è costruito tutto il resto.

Gli otto tipi primitivi

Java ha esattamente otto tipi primitivi predefiniti. Sei sono numeri, uno è un carattere e uno è un booleano:

Alcune cose da notare subito: i trattini bassi in 2_000_000 sono solo separatori visivi che il compilatore ignora, i suffissi L e f sono obbligatori (ne parliamo più avanti), e char usa gli apici singoli mentre una String userebbe le virgolette doppie.

Scegliere un tipo numerico

Non ti servono quasi mai byte o short: fanno risparmiare memoria solo in array enormi. Le vere scelte sono tra int/long per i numeri interi e float/double per i decimali.

TipoDimensioneQuando usarlo
int32 bitIl default per i numeri interi (fino a circa 2,1 miliardi)
long64 bitValori oltre circa 2 miliardi: timestamp in millisecondi, dimensioni di file
double64 bitIl default per i decimali: buona precisione
float32 bitSolo quando la memoria è scarsa e puoi sacrificare precisione

La trappola è l'overflow. Un int ricomincia dal basso in silenzio quando supera il suo intervallo: nessun errore, solo un risultato sbagliato:

maxInt + 1 va in overflow e diventa -2147483648 perché entrambi gli operandi sono int e anche il risultato resta un int. Convertire prima uno dei due lati in long fa eseguire il calcolo a 64 bit. Quando un valore può essere grande, soprattutto i millisecondi dal 1970, usa long.

I letterali e i loro suffissi

Un letterale numerico da solo ha un tipo predefinito, e questo trae spesso in inganno. 100 è un int; 3.14 è un double. Per scrivere un letterale long o float devi aggiungere un suffisso:

Togli la L da 8_000_000_000L e il codice non compila, perché il letterale supera l'intervallo di int prima ancora di arrivare alla variabile long. Togli la f da 0.5f e Java si lamenta che un double non può essere assegnato a un float senza un cast. Il suffisso non distingue tra maiuscole e minuscole, ma usa la L maiuscola: una l minuscola sembra identica alla cifra 1.

char è un numero travestito

Un char memorizza un'unità di codice Unicode a 16 bit, quindi funziona anche come piccolo intero senza segno. Puoi farci dei calcoli e convertirlo avanti e indietro con un cast:

A volte è utile per spostare le lettere, ma non affidarti a questo per il testo: per quello c'è String. Nota che char usa gli apici singoli ('A'); le virgolette doppie ("A") creano una String di un solo carattere, che è un tipo completamente diverso.

Valori predefiniti (e la trappola delle variabili locali)

I campi e gli elementi degli array che non inizializzi ricevono un valore predefinito sensato. Ma questo vale solo per campi e posizioni degli array: le variabili locali non hanno alcun valore predefinito, e usarne una prima di assegnarle un valore è un errore di compilazione, non una sorpresa a runtime.

Se invece scrivessi int x; System.out.println(x); dentro main, il compilatore lo rifiuterebbe con "variable x might not have been initialized". Questa severità è una caratteristica utile: ti impedisce di leggere dati casuali. I valori predefiniti da ricordare: i tipi numerici 0, boolean false, char '�' e ogni tipo riferimento null.

Prossimo passo: le stringhe

String è il tipo riferimento che userai di più: testo, valori concatenati, input dell'utente. Si comporta in modo diverso dai primitivi visti qui: è un oggetto, è immutabile e confrontare stringhe ha le sue insidie. Ne parla la prossima pagina.

Domande frequenti

Quanti tipi di dati ci sono in Java?

Java ha otto tipi primitivi: byte, short, int, long, float, double, char e boolean. Tutto il resto, cioè String, gli array e qualsiasi oggetto, è un tipo riferimento. Quindi il numero di primitivi predefiniti è fisso a otto, mentre i tipi riferimento sono illimitati, perché tu (e le librerie) definite nuove classi.

Qual è la differenza tra int e long in Java?

Entrambi contengono numeri interi, ma int è a 32 bit (intervallo di circa ±2,1 miliardi) e long è a 64 bit (intervallo di circa ±9,2 trilioni). Usa int di default; passa a long quando un valore può superare i due miliardi: timestamp in millisecondi, dimensioni di file, contatori grandi. Un letterale long richiede il suffisso L, per esempio long big = 10000000000L;.

Qual è il valore predefinito di un int in Java?

Un campo int vale 0 di default, ma solo i campi e gli elementi degli array ricevono un valore predefinito. Un long vale 0L, double vale 0.0, boolean vale false, char vale '\u0000' e qualsiasi tipo riferimento vale null. Le variabili locali non ricevono alcun valore predefinito: devi assegnarne uno prima di usarle, altrimenti il codice non compila.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA