كان أحمد رجل أعمال. سافر إلى الولايات المتحدة الأمريكية، ووجد صفقة رائعة في أحد المصانع، فاشترى مليون جهاز إلكتروني — مستثمرًا كل ما يملك. وصلت الشحنة إلى ميناء جدة. فتح الصندوق الأول، وصل الجهاز بالكهرباء... لا شيء. رائحة احتراق. 💨
الأجهزة مصممة لـ 110 فولت، أما المملكة العربية السعودية فتعمل على 220 فولت. مليون جهاز — غير متوافق تمامًا. لا يستطيع بيع جهاز واحد. انتهى مشروعه قبل أن يبدأ.
ثم اتصل به صديقه خالد. "يا أحمد — لا تلمس أي جهاز. ابنِ صندوقًا صغيرًا: يأخذ 220 فولتًا من الحائط، يحوّلها إلى 110 فولت في الداخل، ويعطي جهازك ما يحتاجه بالضبط. ضعه في المنتصف." وضع أحمد صندوق التغليف (Wrapper) في المنتصف — دون أن يتغيّر شيء على أي من الجانبين — ونجح مشروعه. 🎉
لدى Java نفس المشكلة. الأنواع الأساسية (Primitives) (int, double, char...) تعمل بشكل ممتاز وحدها، لكن عالم Java الكائني — ArrayList، والأنواع العامة (Generics)، والمكتبات — يقبل الكائنات (Objects) فقط. حل Java هو بالضبط صندوق خالد: فئة التغليف (Wrapper Class) (Integer, Double, Character...) توضع في المنتصف. لا يتغير شيء على أي من الجانبين.
في Java، توجد 8 أنواع أساسية (Primitive Types): byte, short, int, long, float, double, char, boolean. بعض واجهات برمجة Java وهياكل البيانات (مثل ArrayList) تعمل مع الكائنات (Objects) فقط، وليس مع الأنواع الأساسية. الحل؟ توفر Java فئة تغليف (Wrapper Class) لكل نوع أساسي تقوم بتغليفه داخل كائن!
intValue()، compareTo()، parseInt()...
| النوع الأساسي (Primitive Type) | فئة التغليف (Wrapper Class) | مثال |
|---|---|---|
byte | Byte | Byte b = new Byte((byte)5); |
short | Short | Short s = new Short((short)100); |
int | Integer | Integer i = new Integer(42); |
long | Long | Long l = new Long(100L); |
float | Float | Float f = new Float(3.14f); |
double | Double | Double d = new Double(2.718); |
char | Character | Character c = new Character('A'); |
boolean | Boolean | Boolean b = new Boolean(true); |
فئات التغليف في Java مدمجة في اللغة — لكن يمكنك أيضًا بناء فئة التغليف الخاصة بك. هذه فكرة قوية: خذ أي نوع أساسي، ولفّه داخل صنف، وأضف أي دوال تحتاجها. على سبيل المثال، يمكننا تعريف صنف يسمى MyInt يلفّ نوع int ويوفر وظائف إضافية.
بعض واجهات برمجة Java (مثل ArrayList<Integer> و HashMap<String, Double>) تقبل الكائنات (Objects) فقط (لأنها تستخدم الأنواع العامة Generic). لا يمكنك كتابة ArrayList<int>. لذا تتيح فئات التغليف تخزين قيم الأنواع الأساسية داخل هذه الهياكل.
ميزتا التغليف التلقائي (Autoboxing) وفك التغليف التلقائي (Unboxing) في Java (منذ الإصدار الخامس) تتولّيان معظم التحويلات تلقائيًا، لذلك نادرًا ما تحتاج إلى استدعاء .intValue() يدويًا.
- التغليف التلقائي (Auto-boxing): تحوّل Java تلقائيًا النوع الأساسي إلى نوع التغليف المقابل عند الحاجة.
Integer x = 5;→ تكتب Javanew Integer(5)بدلًا عنك. - فك التغليف التلقائي (Auto-unboxing): تحوّل Java تلقائيًا الكائن المغلّف إلى نوعه الأساسي.
int y = x;→ تستدعي Javax.intValue()بدلًا عنك. - ثوابت مفيدة:
Integer.MAX_VALUE،Integer.MIN_VALUE،Double.MAX_VALUE. - التحليل (Parsing):
Integer.parseInt("42")تحوّلStringإلىint— شائع جدًا في البرامج الفعلية!
ماذا لو كان العدد الذي تحتاج لحسابه كبيرًا جدًا لدرجة أنه لا يسع في نوع long (الذي يبلغ حده الأقصى حوالي 9.2 × 1018)؟ أو تحتاج إلى حساب عشري بدقة بالغة — كما في الحسابات المالية أو التشفير؟
توفر Java صنفين خاصين: BigInteger و BigDecimal في الحزمة java.math.
add()، subtract()، multiply()، divide()، pow()، mod().لا يمكنك استخدام عوامل +، -، *، / مع BigInteger أو BigDecimal. يجب استخدام دوالهما: .add()، .subtract()، .multiply()، .divide().
سأل أحد الطلاب: "لماذا نحتاج في أي وقت لأعداد بهذا الحجم؟"
في علم التشفير (Cryptography)، تتطلب خوارزميات مثل RSA التعامل مع أعداد صحيحة تمتد لمئات الأرقام (مثل أعداد من 2048 بت أو 4096 بت). إن تحليل مثل هذه الأعداد إلى عواملها الأولية هو ما يجعل التشفير آمنًا. وBigInteger هو الأداة القياسية لتطبيق هذه الخوارزميات في Java.
BigInteger وBigDecimal ليسا بالمفهوم الدقيق مفاهيمَ كائنية التوجه (OOP) — بل هما ميزتان من مكتبة Java. ندرسهما هنا لأنهما يوضحان كيف تُغلّف Java سلوكًا عدديًا معقدًا داخل أصناف بدوال، وهو مثال رائع على مبدأي التغليف (Encapsulation) والتجريد (Abstraction) في العمل.
new. رمز UML: معين مملوء ◆.Student supervisor داخل Student). أساس القوائم المترابطة (Linked Lists) في هياكل البيانات.1، 0..1، *، 1..*، ومدى مثل 5..60.int → Integer) لتمكينه من الاستخدام ككائن. يتولى التغليف التلقائي (Autoboxing) وفك التغليف التلقائي (Unboxing) التحويلات تلقائيًا.add()، multiply()) — لا عوامل الحساب. ضرورية للتشفير والحسابات المالية.