è la conversione automatica di Java tra (, ) e i loro (, ). È conveniente ma ha rischi sottili — overhead di performance, comportamento sorprendente di , e rischio di .
è la conversione automatica di Java tra (, ) e i loro (, ). È conveniente ma ha rischi sottili — overhead di performance, comportamento sorprendente di , e rischio di .
intdoubleIntegerDouble==NullPointerExceptionInteger boxed = 42; // autoboxing: int → Integer (Integer.valueOf(42))
int unboxed = boxed; // auto-unboxing: Integer → int (boxed.intValue())
List<Integer> nums = new ArrayList<>();
nums.add(5); // autoboxes int 5 → Integer (collections need objects)
int x = nums.get(0); // auto-unboxes Integer → int
Accade automaticamente perché le collezioni e i generics richiedono oggetti (non puoi avere List<int>), quindi Java incapsula i primitivi in modo trasparente.
Integer a = 1000;
Integer b = 1000;
a == b; // ❌ FALSE — different Integer OBJECTS (reference comparison)
a.equals(b); // ✅ true — value comparison
// the WORSE trap — the Integer cache makes small values seem to work:
Integer c = 100, d = 100;
c == d; // TRUE — Java CACHES Integers from -128 to 127 (same object)
Integer e = 200, f = 200;
e == f; // FALSE — outside the cache range → different objects
Questo è insidioso: == su Integer funziona per valori piccoli (memorizzati in cache) ma fallisce per quelli grandi — il codice che sembra corretto nei test si rompe in produzione. Usa sempre .equals() per il confronto dei valori dei wrapper, oppure unbox ai primitivi prima.
Integer value = null; // a wrapper can be null
int x = value; // 💥 NullPointerException — unboxing null calls null.intValue()
Map<String, Integer> map = new HashMap<>();
int count = map.get("missing"); // 💥 NPE — get() returns null, then unboxing fails
L'unboxing di un wrapper null lancia una NPE — un crash comune e sorprendente, specialmente con i lookups delle mappe che restituiscono null.
// ❌ autoboxing in a hot loop — creates millions of Integer objects (GC pressure, slow)
Long sum = 0L; // WRONG type — wrapper
for (long i = 0; i < 1_000_000; i++) {
sum += i; // unbox, add, re-box → new Long each iteration!
}
// ✅ use primitives in hot paths
long sum = 0L; // primitive — no boxing
L'autoboxing/unboxing ripetuto crea oggetti eccessivi, danneggiando le performance in loop stretti.
L'autoboxing è conveniente e pervasivo (le collezioni e i generics vi si affidano tutti), ma i suoi rischi causano bug reali e difficili da diagnosticare.
La trappola di == è particolarmente pericolosa: il confronto di Integer con == funziona per valori piccoli memorizzati in cache (da -128 a 127) ma fallisce silenziosamente per quelli più grandi — un bug che passa i test e si rompe in produzione — rendendo .equals() (o l'unboxing) essenziale per il confronto dei wrapper. NullPointerExceptions derivanti dall'unboxing di wrapper null (comuni nei lookups delle mappe) sono un altro crash frequente.
E il boxing in loop critici crea oggetti inutili, danneggiando le performance.
Comprendere quando si verifica il boxing, il problema del confronto tra valore e riferimento, il rischio di null-unboxing, e l'uso di primitivi nel codice critico per le performance è importante per scrivere Java corretto ed efficiente — e il comportamento di == della cache Integer è una domanda classica di intervista che rivela una comprensione profonda.