Insidie dell'autoboxing
Unboxing di null e trappole di ==
Insidie dell'autoboxing è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 4 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.
La comodità nasconde delle insidie
L'autoboxing rende il codice più pulito, ma nasconde conversioni che possono causare bug sorprendenti. Le due insidie principali sono l'unboxing di null e il confronto dell'identità con ==.
Questa lezione mostra come evitare entrambe.
L'insidia dell'unboxing di null
Se un wrapper contiene null e viene convertito in un primitivo tramite unboxing, Java genera una NullPointerException.
È facile non accorgersene, perché il codice sembra una semplice assegnazione.
public class Main {
public static void main(String[] args) {
Integer maybe = null;
try {
int value = maybe;
System.out.println(value);
} catch (NullPointerException e) {
System.out.println("Cannot unbox null!");
}
}
}Null nell'aritmetica
L'insidia si presenta anche all'interno delle espressioni. L'aggiunta di un wrapper null ne esegue prima l'unboxing, che genera un'eccezione prima ancora che il calcolo venga eseguito.
public class Main {
public static void main(String[] args) {
Integer count = null;
try {
int total = count + 5;
System.out.println(total);
} catch (NullPointerException e) {
System.out.println("Null in arithmetic!");
}
}
}Prevenire i valori null
Controlli sempre che un wrapper non valga null prima di eseguirne l'unboxing, oppure fornisca un valore predefinito.
public class Main {
public static void main(String[] args) {
Integer maybe = null;
int safe = (maybe != null) ? maybe : 0;
System.out.println(safe);
}
}La sorpresa della cache di ==
Integer.valueOf memorizza nella cache i valori compresi tra -128 e 127. Di conseguenza, due valori sottoposti a boxing in quell'intervallo possono condividere lo stesso oggetto e == restituisce true.
public class Main {
public static void main(String[] args) {
Integer a = 100;
Integer b = 100;
System.out.println(a == b);
}
}Al di fuori della cache
Al di sopra dell'intervallo della cache, ogni operazione di boxing crea un oggetto distinto. In questo caso == confronta i riferimenti e restituisce false anche se i numeri sono uguali.
public class Main {
public static void main(String[] args) {
Integer a = 200;
Integer b = 200;
System.out.println(a == b);
}
}Usi sempre equals
Poiché == sui wrapper confronta l'identità degli oggetti, deve usare .equals() per confrontare i valori numerici effettivi.
public class Main {
public static void main(String[] args) {
Integer a = 200;
Integer b = 200;
System.out.println(a.equals(b));
}
}Combinare == con un primitivo
Se uno dei due lati di == è un primitivo, Java esegue l'unboxing del wrapper, quindi il confronto avviene per valore. È affidabile, ma può comunque generare un'eccezione se il wrapper è null.
public class Main {
public static void main(String[] args) {
Integer a = 200;
int b = 200;
System.out.println(a == b);
}
}Boxing implicito nei cicli
Dichiarare l'accumulatore di un ciclo come wrapper crea un nuovo oggetto a ogni iterazione. Nell'esempio seguente, usare Long invece di long eseguirebbe ripetutamente il boxing. Preferisca il primitivo.
public class Main {
public static void main(String[] args) {
long sum = 0;
for (int i = 0; i < 1000; i++) {
sum += i;
}
System.out.println(sum);
}
}Map.get restituisce null
Un bug comune nel mondo reale: Map.get restituisce null quando la chiave non esiste. Eseguire l'unboxing di quel risultato in un int genera un'eccezione. Utilizzi invece getOrDefault.
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
int score = scores.getOrDefault("missing", 0);
System.out.println(score);
}
}Operare in sicurezza
Due abitudini prevengono la maggior parte dei bug di autoboxing: non esegua mai l'unboxing di un valore che potrebbe essere null e confronti sempre i valori dei wrapper con .equals() anziché con ==.
Verifica rapida
Verifichi la sua consapevolezza dei problemi dell'autoboxing.
Riepilogo
Ha imparato a conoscere i principali problemi dell'autoboxing:
- L'unboxing di un wrapper
nullgenera unaNullPointerException - Utilizzi un controllo di nullità o un valore predefinito come protezione
==sui wrapper confronta i riferimenti, con caching da -128 a 127- Usi sempre
.equals()per confrontare i valori - Utilizzi
getOrDefaultper evitare il valore null nelle ricerche nelle mappe
Domande Frequenti
La lezione «Insidie dell'autoboxing» è gratuita?
Sì — il testo completo di «Insidie dell'autoboxing» è 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 «Insidie dell'autoboxing»?
Unboxing di null e trappole di == 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 4 di 4.
Quanto tempo richiede la lezione «Insidie dell'autoboxing»?
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 wrapper
- Autoboxing e unboxing
- Parsing e valueOf
- Insidie dell'autoboxing