فئات التغليف والتعبئة التلقائية
فئات التغليف والتعبئة التلقائية
أنواع Java البدائية — int وdouble وboolean وغيرها — سريعة وكفؤة في استهلاك الذاكرة، لكنها ليست كائنات. يصبح هذا مشكلة حين تحتاج إلى تخزينها في مجموعة، أو تمريرها لدالة تتوقع Object، أو استدعاء دالة مساعدة على رقم. تحل فئات التغليف هذه المشكلة بلف كل نوع بدائي داخل كائن حقيقي.
فئات التغليف الثماني
لكل نوع بدائي فئة مقابلة في حزمة java.lang:
byte→Byteshort→Shortint→Integerlong→Longfloat→Floatdouble→Doublechar→Characterboolean→Boolean
ستتعامل مع Integer وDouble وBoolean أكثر من غيرها، فهي الأكثر شيوعًا في كود Java اليومي.
التعبئة التلقائية وفك التعبئة
قبل الإصدار Java 5 كان عليك إجراء التحويل يدويًا. اليوم تقوم Java بذلك تلقائيًا:
- التعبئة التلقائية (Autoboxing) — يحوّل المُترجِم النوع البدائي إلى كائن تغليف تلقائيًا.
- فك التعبئة (Unboxing) — يحوّل المُترجِم كائن التغليف إلى النوع البدائي تلقائيًا.
يبدو التحويل غير مرئي على مستوى الكود المصدري، لكن المُترجِم يُدرج الاستدعاءات. فهم هذا مهم للأداء وللخطأ الخفي الذي ستراه لاحقًا.
دوال مفيدة في فئات التغليف
فئات التغليف ليست مجرد حاويات — فهي تحمل دوالًا ثابتة مساعدة لا تستطيع الأنواع البدائية امتلاكها.
تحليل النصوص إلى أنواع بدائية
من أكثر استخدامات فئات التغليف شيوعًا تحليل مدخلات المستخدم أو قيم الضبط المُخزَّنة كنص إلى أرقام أو قيم منطقية صالحة للاستخدام.
Integer.parseInt("42") نوعًا بدائيًا int. تُعيد Integer.valueOf("42") كائن Integer (مع الاستفادة من الذاكرة المؤقتة المذكورة لاحقًا). فضّل parseInt حين تحتاج نوعًا بدائيًا، وفضّل valueOf حين تحتاج كائنًا.
فخ ذاكرة Integer التخزينية
إليك أحد أشهر مزالق المبتدئين في Java. تُخزّن JVM كائنات Integer للقيم الواقعة بين -128 و127 شاملةً. حين تُعبَّأ قيمة في هذا النطاق تلقائيًا، تستعيد الكائن المُخزَّن ذاته في كل مرة. أما خارج هذا النطاق فيُنشأ كائن جديد في كل مرة.
== تطابق المرجع (هل هذان الكائنان نفس الكائن في الذاكرة؟)، لا تساوي القيمة. كائنَا Integer اللذان يحملان 200 كائنان مختلفان و== يُعيد false. استخدم دائمًا .equals() لمقارنة قيم التغليف.
القيمة null وخطأ NullPointerException عند فك التعبئة
نظرًا لأن كائنات التغليف كائنات حقيقية، يمكن أن تكون null. يُطلق فك تعبئة قيمة null استثناء NullPointerException — مصدر شائع للأعطال عند العمل مع المجموعات أو قيم الإرجاع من الدوال.
value.intValue(). استدعاء أي دالة على null يُطلق NullPointerException. لا يستطيع المُترجِم تحذيرك لأن الإسناد يبدو قانونيًا — احرص دائمًا على حماية مراجع التغليف التي قد تكون null.
الخلاصة
تُجسّر فئات التغليف الهوّة بين الأنواع البدائية وعالم الكائنات. تتيح لك التعبئة التلقائية وفك التعبئة كتابة كود طبيعي بينما يتولى المُترجِم التحويلات. احتفظ بثلاث قواعد في ذهنك: استخدم parseInt وparseDouble لتحويل النصوص إلى قيم؛ قارن التغليفات دائمًا بـ.equals() لا بـ==؛ واحرص على الحماية من null قبل فك التعبئة. بهذه العادات ستتجنب أكثر الأخطاء شيوعًا المرتبطة بالتغليف.