هو تحويل Java التلقائي بين (, ) و (, ). إنه مريح لكنه يحتوي على مخاطر دقيقة — overhead الأداء، سلوك المفاجئ، وخطر .
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
يحدث تلقائياً لأن collections و generics تتطلب objects (لا يمكنك أن تملك List<int>)، لذا فإن Java تقوم بـ boxing primitives بشفافية.
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
هذا خطير جداً: == على Integer يعمل للقيم الصغيرة (مخزنة مؤقتاً) لكنه يفشل للقيم الكبيرة — الكود الذي يبدو صحيحاً في الاختبار ينكسر في الإنتاج. استخدم دائماً .equals() لمقارنة قيم wrapper، أو قم بـ unbox إلى primitives أولاً.
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
Unboxing null wrapper يرمي NPE — انهيار شائع ومفاجئ، خاصة مع map lookups التي تعود 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
Boxing/unboxing المتكرر ينشئ objects زائدة عن الحاجة، مما يضر بالأداء في الحلقات المغلقة.
Autoboxing مريح وشامل (collections و generics تعتمد عليه جميعاً)، لكن مخاطره تسبب أخطاء حقيقية وصعبة التشخيص.
فخ == خطير بشكل خاص: مقارنة Integer مع == تعمل للقيم الصغيرة المخزنة مؤقتاً (-128 إلى 127) لكنها تفشل بصمت للقيم الأكبر — خطأ يمر في الاختبارات وينكسر في الإنتاج — مما يجعل .equals() (أو unboxing) ضرورياً لمقارنة wrapper. NullPointerExceptions من unboxing null wrappers (شائعة مع map lookups) هي عطل متكرر آخر.
وـboxing في hot loops ينشئ objects لا داعي لها، مما يضر بالأداء.
فهم متى يحدث boxing، مسألة مقارنة القيمة مقابل المرجع، خطر null-unboxing، واستخدام primitives في الكود الحرج من حيث الأداء مهم لكتابة Java صحيحة وفعالة — والسلوك == للـ Integer-cache هو سؤال مقابلة كلاسيكي يكشف الفهم العميق.