Tipi di dati in Java
Esplora i tipi primitivi di Java (byte, short, int, long, float, double, char, boolean) e i tipi reference.
Java è staticamente tipizzato — ogni variabile ha un tipo noto a tempo di compilazione. I tipi si dividono in due famiglie: i primitivi (valori grezzi integrati nel linguaggio) e i tipi reference (oggetti, array, qualsiasi cosa creata con new). Questo capitolo illustra entrambi.
Gli otto tipi primitivi
I primitivi sono gli unici valori in Java che non sono oggetti. Memorizzano il loro valore direttamente nello slot di archiviazione della variabile. Java ne definisce esattamente otto:
| Tipo | Dimensione | Intervallo | Default | Esempio letterale |
|---|---|---|---|---|
byte | 8 bit | da -128 a 127 | 0 | byte b = 100; |
short | 16 bit | da -32.768 a 32.767 | 0 | short s = 30000; |
int | 32 bit | da -2³¹ a 2³¹-1 (≈ ±2,1 miliardi) | 0 | int i = 1_000_000; |
long | 64 bit | da -2⁶³ a 2⁶³-1 | 0L | long l = 9_000L; |
float | 32 bit | IEEE 754 singola precisione | 0.0f | float f = 3.14f; |
double | 64 bit | IEEE 754 doppia precisione | 0.0 | double d = 3.14; |
char | 16 bit | Unità di codice Unicode (da U+0000 a U+FFFF) | \0 | char c = 'A'; |
boolean | definito da JVM | true oppure false | false | boolean b = true; |
Alcune cose che vale la pena ricordare:
intè il tipo intero predefinito. La maggior parte dei contatori e degli indici sonoint. Usalongsolo quando hai effettivamente bisogno di numeri superiori a circa 2 miliardi.doubleè il tipo a virgola mobile predefinito.3.14senza suffisso è undouble;3.14fè unfloat. Usadoublea meno che la pressione sulla memoria non impongafloat.- I trattini bassi nei letterali numerici migliorano la leggibilità:
1_000_000equivale a1000000. - I valori predefiniti si applicano solo ai campi, non alle variabili locali. Una variabile locale non ha un valore predefinito — devi inizializzarla prima di leggerla.
Tipi reference
Tutto il resto — String, array, le tue classi, le classi di libreria — è un tipo reference. Una variabile di tipo reference non contiene l'oggetto stesso; contiene un riferimento (essenzialmente un puntatore) all'oggetto nello heap:
String name = "Ada";
int[] scores = new int[10];
LocalDate today = LocalDate.now();Il valore predefinito di qualsiasi variabile reference è null — un valore speciale che significa "nessun oggetto."
String s = null;
System.out.println(s.length()); // throws NullPointerException at runtimenull è la causa di uno degli errori a runtime più comuni in Java. Il capitolo Java Exceptions spiega come gestire la NullPointerException che questo genera.
Classi wrapper
Ogni primitivo ha una classe wrapper corrispondente — un vero oggetto che racchiude il valore primitivo:
| Primitivo | Wrapper |
|---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
I wrapper sono necessari quando si vogliono inserire primitivi nelle collection (che contengono solo oggetti):
List<Integer> scores = new ArrayList<>();
scores.add(42); // autoboxed from int → Integer
int first = scores.get(0); // unboxed from Integer → intJava converte automaticamente tra primitivi e wrapper — questa operazione si chiama autoboxing e unboxing — quindi nella maggior parte dei casi non se ne accorge.
Una nota su String
String è un tipo reference, non un primitivo. È abbastanza speciale da avere una sintassi letterale ("testo") e l'operatore +. Le stringhe sono immutabili — una volta create, il loro contenuto non cambia mai. Ogni "modifica" restituisce una nuova stringa. Il capitolo Java Strings approfondisce l'argomento.
Scegliere un tipo
Un breve albero decisionale per l'uso quotidiano di Java:
- Contare oggetti o usare indici di array →
int - Conteggi grandi (dimensioni di file, timestamp in millisecondi) →
long - Denaro →
BigDecimal(nondouble— l'arrotondamento in virgola mobile ti porterà problemi) - Un singolo carattere →
char - Sì/no →
boolean - Testo →
String - Una data o un'ora → i tipi in
java.time(LocalDate,Instant,Duration)
Resisti alla tentazione di "risparmiare memoria" usando byte o short per interi ordinari. Le JVM sono ottimizzate per le operazioni su int; short non usa effettivamente meno memoria nella maggior parte dei casi.
Insidie comuni
Alcuni comportamenti dei tipi sorprendono regolarmente i principianti. Conoscerli in anticipo fa risparmiare ore di debug.
L'overflow degli interi avviene silenziosamente
L'aritmetica sugli interi in Java non genera mai un'eccezione per overflow — si avvolge. Aggiungere 1 al valore massimo di int produce il valore minimo di int:
int max = Integer.MAX_VALUE; // 2147483647
System.out.println(max + 1); // -2147483648Se un valore potrebbe superare circa 2,1 miliardi, usa long. Per conteggi che potrebbero far overflow anche con long, ricorri a BigInteger.
La virgola mobile non è esatta
float e double seguono lo standard IEEE 754, che non può rappresentare la maggior parte delle frazioni decimali con esattezza. L'esempio classico:
System.out.println(0.1 + 0.2); // 0.30000000000000004Ecco perché non dovresti mai usare double per il denaro. Usa BigDecimal (costruito da una String, ad es. new BigDecimal("0.1")) quando i valori decimali esatti sono importanti.
char è un numero
Un char è un intero senza segno a 16 bit che contiene un'unità di codice Unicode, quindi partecipa all'aritmetica:
char a = 'A';
System.out.println((int) a); // 65
System.out.println((char) (a + 1)); // BConfronta i wrapper con .equals(), non con ==
== su oggetti wrapper confronta i riferimenti, non i valori. A causa di una cache di autoboxing per i valori Integer piccoli (da -128 a 127), == sembra funzionare per numeri piccoli e poi fallisce per quelli grandi:
Integer a = 127, b = 127;
System.out.println(a == b); // true (cached)
Integer c = 128, d = 128;
System.out.println(c == d); // false (different objects)
System.out.println(c.equals(d)); // true (compares values)Usa sempre .equals() per confrontare i valori wrapper. Vedi Java Type Casting per le regole sulla conversione tra questi tipi.
Una dimostrazione pratica
Cosa c'è dopo
Java Type Casting mostra come convertire tra tipi numerici e tra tipi reference correlati.