Ce face Tipuri wrapper și autoboxing
Fiecare tip primitiv are o clasă wrapper: byte → Byte, short → Short, int → Integer, long → Long, float → Float, double → Double, char → Character, boolean → Boolean. Ai nevoie de ele acolo unde Java cere obiecte, de exemplu în colecții: List<Integer>, nu List<int>.
Din Java 5, compilatorul face conversia automat: Integer n = 5; (autoboxing) și int m = n; (unboxing). Clasele wrapper au și metode utile: Integer.parseInt, Double.parseDouble, Integer.MAX_VALUE, Character.isDigit.
Un wrapper poate fi null, un primitiv nu. Unboxing-ul unui null aruncă NullPointerException. Wrapper-ele sunt obiecte, deci se compară cu equals, nu cu ==.
Exemple
Exemplul 1: Autoboxing în colecții
Numerele int sunt împachetate automat în Integer când intră în listă și despachetate când sunt adunate într-o variabilă int.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> note = new ArrayList<>();
note.add(9); // autoboxing
note.add(10);
note.add(7);
int suma = 0;
for (int nota : note) { // unboxing
suma += nota;
}
System.out.println("note: " + note + ", sumă: " + suma);
Integer maxim = Integer.MAX_VALUE;
System.out.println("Integer.MAX_VALUE = " + maxim);
System.out.println("parseInt(\"2026\") + 1 = " + (Integer.parseInt("2026") + 1));
System.out.println("Double.valueOf(\"9.5\") = " + Double.valueOf("9.5"));
}
}
Rezultat
note: [9, 10, 7], sumă: 26
Integer.MAX_VALUE = 2147483647
parseInt("2026") + 1 = 2027
Double.valueOf("9.5") = 9.5
Exemplul 2: Capcanele: == și null
Pentru valori între −128 și 127, Integer folosește obiecte din cache, deci == pare să meargă; pentru 1000 se creează obiecte diferite și == dă false. equals compară corect valorile. Unboxing-ul lui null aruncă excepție.
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Integer a = 100, b = 100;
Integer c = 1000, d = 1000;
System.out.println("100 == 100: " + (a == b));
System.out.println("1000 == 1000: " + (c == d));
System.out.println("1000 equals 1000: " + c.equals(d));
Map<String, Integer> stoc = new HashMap<>();
stoc.put("mere", 12);
Integer pere = stoc.get("pere"); // nu există: null
System.out.println("pere: " + pere);
try {
int cantitate = pere; // unboxing de null
System.out.println(cantitate);
} catch (NullPointerException e) {
System.out.println("NullPointerException la unboxing");
}
int sigur = stoc.getOrDefault("pere", 0);
System.out.println("cu getOrDefault: " + sigur);
}
}
Rezultat
100 == 100: true
1000 == 1000: false
1000 equals 1000: true
pere: null
NullPointerException la unboxing
cu getOrDefault: 0
Greșeli frecvente
- Compararea a două
Integercu==: merge pentru valori mici (cache) și greșește pentru altele. Foloseșteequalssau despachetează înint. - Unboxing-ul unui
null(de exemplu dinmap.get) aruncăNullPointerException. - Wrapper-e în bucle cu multe calcule (
Long suma): fiecare pas creează un obiect nou și este mult mai lent decâtlong.
Comenzi înrudite
Variabile și tipuri primitive: O variabilă are un tip fix, declarat la creare; Java are 8 tipuri primitive: byte, short, int, long, float, double, char, boolean.int, long, short și byte: Tipurile întregi din Java: int (32 de biți) pentru aproape orice, long pentru valori mari, short și byte pentru economie de memorie.Generics (tipuri generice): Generics parametrizează clase și metode cu tipuri (List<String>, Map<String, Integer>), ca erorile de tip să apară la compilare, nu la rulare.equals și hashCode: equals decide când două obiecte sunt „egale” ca valoare; hashCode trebuie rescris împreună cu el, altfel HashMap și HashSet nu funcționează corect.