Tipi primitivi e tipi di riferimento
Comprenda la differenza fondamentale tra tipi primitivi e tipi di riferimento in Java.
Tipi primitivi e tipi di riferimento è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.
Tipi primitivi e tipi di riferimento
Java dispone di due categorie fondamentali di tipi di dati: tipi primitivi e tipi di riferimento. Comprendere la differenza è fondamentale per scrivere codice Java corretto ed efficiente.
Gli otto tipi primitivi
Java dispone esattamente di otto tipi primitivi:
byte(intero a 8 bit)short(intero a 16 bit)int(intero a 32 bit)long(intero a 64 bit)float(numero decimale a 32 bit)double(numero decimale a 64 bit)char(carattere Unicode a 16 bit)boolean(true/false)
I primitivi contengono direttamente il valore in memoria, senza l'overhead di un oggetto.
int age = 25;
double price = 19.99;
boolean active = true;
char grade = 'A';
long population = 8_000_000_000L;
System.out.println(age); // 25
System.out.println(price); // 19.99
System.out.println(active); // trueTipi di riferimento
Un tipo di riferimento memorizza un indirizzo di memoria (un riferimento) che punta a un oggetto nell'heap. Questa categoria include:
- Classi (ad esempio,
String,Scanner) - Array (ad esempio,
int[]) - Interfacce
- Enum e record
La variabile non contiene l'oggetto, ma un puntatore a esso.
String name = "Alice"; // reference to a String object
int[] scores = {90, 85, 92}; // reference to an array object
// name holds a reference, not the characters directly
System.out.println(name.length()); // 5
System.out.println(scores.length); // 3Memoria stack e heap
Le variabili primitive vengono memorizzate nello stack, una memoria veloce e di breve durata legata alle chiamate di metodo.
Gli oggetti dei tipi di riferimento risiedono nell'heap, una memoria più ampia e longeva gestita dal garbage collector. Il riferimento (l'indirizzo) si trova nello stack.
// Stack: holds the int value directly
int x = 42;
// Stack: holds reference; Heap: holds the Person object
class Person {
String name;
int age;
}
Person p = new Person(); // p is a reference on stack, object on heap
p.name = "Bob";
p.age = 30;null: il riferimento assente
Alle variabili di riferimento può essere assegnato null, a indicare che non puntano ad alcun oggetto. I primitivi non possono essere null: hanno sempre un valore.
L'accesso a un riferimento null causa una NullPointerException (NPE), uno degli errori di runtime più comuni di Java.
String s = null;
// int n = null; // Compile error — primitives can't be null
try {
System.out.println(s.length()); // NullPointerException!
} catch (NullPointerException e) {
System.out.println("Caught NPE: reference was null");
}Semantica della copia: primitivi
Quando si assegna una variabile primitiva a un'altra, Java copia il valore. La modifica di una non influisce sull'altra: sono completamente indipendenti.
int a = 10;
int b = a; // b gets a copy of the value 10
b = 20; // changing b does NOT affect a
System.out.println(a); // 10
System.out.println(b); // 20Semantica della copia: riferimenti
Quando si assegna una variabile di riferimento a un'altra, entrambe le variabili puntano allo stesso oggetto. Le modifiche apportate all'oggetto tramite un riferimento sono visibili anche tramite l'altro.
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1; // arr2 points to the SAME array
arr2[0] = 99; // modifies the shared array
System.out.println(arr1[0]); // 99 — arr1 sees the change too!
System.out.println(arr2[0]); // 99Classi wrapper: boxing dei primitivi
Ogni primitivo ha una classe wrapper corrispondente in java.lang:
int→Integerdouble→Doubleboolean→Booleanchar→Character
Le classi wrapper permettono di utilizzare i primitivi come oggetti, come richiesto dalle collezioni quali List<Integer>.
Integer boxed = Integer.valueOf(42); // explicit boxing
int unboxed = boxed.intValue(); // explicit unboxing
// Autoboxing / auto-unboxing (Java does this automatically)
Integer auto = 100; // autoboxed
int val = auto; // auto-unboxed
System.out.println(Integer.MAX_VALUE); // 2147483647
System.out.println(Double.MIN_VALUE); // 5.0E-324Insidie dell'autoboxing
L'autoboxing è comodo, ma può causare bug difficili da individuare. Integer memorizza nella cache i valori da -128 a 127; al di fuori di questo intervallo, == confronta i riferimenti e non i valori.
Utilizzare sempre .equals() per confrontare oggetti wrapper.
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true (cached)
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // false (different objects!)
System.out.println(c.equals(d)); // true (correct comparison)Passaggio ai metodi: passaggio per valore
In Java il passaggio avviene sempre per valore. Per i primitivi viene copiato il valore. Per i riferimenti viene copiato il riferimento (l'indirizzo): entrambi puntano allo stesso oggetto, ma non è possibile riassegnare dall'interno del metodo la variabile del chiamante.
static void doubleValue(int n) {
n = n * 2; // only modifies the local copy
}
static void clearArray(int[] arr) {
arr[0] = 0; // modifies the shared object
}
int x = 5;
doubleValue(x);
System.out.println(x); // still 5
int[] nums = {10, 20, 30};
clearArray(nums);
System.out.println(nums[0]); // 0 — object was mutatedTabella riepilogativa pratica
Riferimento rapido per confrontare tipi primitivi e tipi di riferimento:
- Memorizzazione: primitivo → valore nello stack; riferimento → indirizzo nello stack + oggetto nell'heap
- Valore predefinito: primitivo → 0/false/\u0000; riferimento → null
- Può essere null: primitivo → No; riferimento → Sì
- La copia durante l'assegnazione è: primitivo → valore; riferimento → indirizzo
- Nelle collezioni: i primitivi richiedono classi wrapper
Verifica rapida
Che cosa accade quando si esegue il seguente codice?
Integer x = 200; Integer y = 200; System.out.println(x == y);
Riepilogo: tipi primitivi e tipi di riferimento
Punti chiave della lezione:
- Java dispone di 8 tipi primitivi memorizzati direttamente nello stack
- I tipi di riferimento memorizzano l'indirizzo di un oggetto nell'heap; la variabile contiene l'indirizzo
- I primitivi vengono copiati per valore; i riferimenti vengono copiati per indirizzo
- Le variabili di riferimento possono essere null; i primitivi no
- Le classi wrapper (Integer, Double ecc.) trasformano i primitivi in oggetti tramite boxing
- In Java il passaggio avviene sempre per valore, anche quando si passano riferimenti
Domande Frequenti
La lezione «Tipi primitivi e tipi di riferimento» è gratuita?
Sì — il testo completo di «Tipi primitivi e tipi di riferimento» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.
Cosa imparerò in «Tipi primitivi e tipi di riferimento»?
Comprenda la differenza fondamentale tra tipi primitivi e tipi di riferimento in Java. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Java Academy?
Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Tipi primitivi e tipi di riferimento»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Java Academy?
Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Tipi primitivi e tipi di riferimento
- Conversioni con ampliamento e restringimento
- L'operatore instanceof
- Il cast dei tipi nella pratica