Menu
flag Ar iconالعربيةdown icon

تحويل الأنواع في Java: التوسيع والتضييق والتحويلات

كيف تحوّل Java بين الأنواع - التوسيع التلقائي، وتحويلات التضييق الصريحة، وما الذي تفقده من بيانات عند التضييق، والتحويل بين الأرقام والنصوص.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

ماذا يعني تحويل الأنواع

تتميز Java بأنها ساكنة الأنواع: لكل قيمة نوع، ولن يسمح لك المُترجم بخلط الأنواع غير المتوافقة دون إشعار. تحويل الأنواع هو الطريقة التي تحوّل بها قيمة من نوع إلى آخر - أحيانًا تقوم Java بذلك نيابةً عنك، وأحيانًا عليك طلبه صراحةً.

هناك اتجاهان. الانتقال من نوع أصغر إلى نوع أكبر (من int إلى double) آمن ويحدث تلقائيًا. أما الانتقال من نوع أكبر إلى نوع أصغر (من double إلى int) فقد يفقد بيانات، لذا تُجبرك Java على توضيح ذلك صراحةً عبر التحويل.

التوسيع: التحويل التلقائي

تحويل التوسيع ينقل قيمة إلى نوع ذي مساحة أكبر. لا يمكن أن يُفقد شيء، لذا تقوم Java بذلك نيابةً عنك دون تحويل:

تندرج القيمة 7 من النوع int داخل double فتصبح 7.0. ترتيب التوسيع للأرقام هو byte -> short -> int -> long -> float -> double؛ والإسناد على امتداد هذه السلسلة من البداية نحو النهاية لا يحتاج أبدًا إلى تحويل. ولهذا السبب غالبًا ما يعمل خلط الأنواع في العمليات الحسابية "من تلقاء نفسه" - إذ توسّع Java المعامل الأصغر أولًا.

التضييق: التحويل الصريح

في الاتجاه الآخر - تحويل التضييق - قد تُفقد بيانات، لذا يرفض المُترجم ذلك ما لم تضع النوع الهدف بين قوسين أمام القيمة:

(int) pi هو التحويل. لاحظ ما يفعله: إنه يقتطع باتجاه الصفر، فيتخلص ببساطة من الجزء العشري. تصبح 3.9 هي 3، وتصبح -3.9 هي -3. إنه لا يقرّب. وإذا أردت التقريب، فتلك أداة مختلفة:

نسيان أن التحويل يقتطع هو من أكثر الأخطاء شيوعًا بين المبتدئين - فإذا كان رقمك "المقرَّب" أقل دائمًا بمقدار واحد، فهذا هو السبب عادةً.

فخ القسمة الصحيحة

هذا الفخ يقع فيه الجميع مرة واحدة. عندما يكون كلا المعاملين من النوع int، يُجري عامل / قسمة صحيحة ويتخلص من الباقي - وذلك قبل أي إسناد إلى double:

a / b هي 7 / 2، تُحسب بالكامل بحساب int، فتعطي 3. والتوسيع إلى double بعد ذلك يحوّل 3 إلى 3.0 فقط - أما الجزء .5 فقد ضاع بالفعل. وتحويل أحد المعاملين إلى double أولًا ((double) a / b) يجبر التعبير كله على الانتقال إلى الفاصلة العائمة، فيعطي 3.5 التي أردتها. تحتاج إلى تحويل جانب واحد فقط؛ وتوسّع Java الجانب الآخر ليطابقه.

عندما يفيض التضييق

لا يتحقق التحويل مما إذا كانت القيمة تتسع. فإن لم تتسع، تُقتطع البتات ببساطة وتحصل على نتيجة مفاجئة - دون خطأ ودون تحذير:

لا تتسع 300 داخل byte، لذا تُحذف البتات العليا فتحصل على 44. هذا فقدان بيانات "صامت" - إذ يعمل البرنامج بسلاسة ويعطي إجابة خاطئة. لا تُضيّق إلا عندما تكون متأكدًا من أن القيمة تتسع في النوع الأصغر.

التحويل بين الأرقام والنصوص

String كائن وليس رقمًا، لذا لا يمكنك تحويله باستخدام (int) - فهذا خطأ في الترجمة. يستخدم التحويل دوالًا مخصصة بدلًا من ذلك:

للانتقال من النص إلى رقم تُستخدم Integer.parseInt / Double.parseDouble. وإذا لم يكن النص رقمًا صالحًا (مثل "hello")، فإن هاتين الدالتين تطلقان استثناء NumberFormatException. وللانتقال من رقم إلى نص، استخدم String.valueOf(n) أو اربطه ببساطة مع "" - لأن n + "" يجبر int على أن يصبح String. وانتبه للفرق بين "5" + 1 (التي تعطي النص "51") و5 + 1 (التي تعطي 6)؛ فعامل + يعني الربط في اللحظة التي يدخل فيها String.

تحويل الكائنات

ينطبق التحويل أيضًا على مراجع الكائنات، لا على الأنواع البدائية وحدها. يمكنك تحويل مرجع إلى نوع ذي صلة على امتداد سلسلة الوراثة - فالتوسيع إلى نوع أب يحدث تلقائيًا، أما التضييق رجوعًا إلى الأسفل فيحتاج إلى تحويل صريح ولا يكون آمنًا إلا إذا كان الكائن من ذلك النوع فعلًا:

Object o = "hello";
String s = (String) o;        // OK: o يشير فعلًا إلى String
Integer bad = (Integer) o;    // يُترجم، لكنه يطلق ClassCastException أثناء التشغيل

التحويل الثاني يُترجم لكنه ينهار أثناء التشغيل مطلقًا استثناء ClassCastException لأن الكائن من النوع String وليس Integer. ستتعرّف على هذا بشكل وافٍ عندما تصل إلى الوراثة وتعدد الأشكال؛ أما الآن فيكفي أن تعرف أن صيغة (Type) هي الفكرة نفسها مطبَّقة على الكائنات.

التالي: if-else

يتيح لك التحويل إعادة تشكيل القيم؛ والخطوة التالية هي جعل برنامجك يختار بين المسارات بناءً على تلك القيم. تُنفّذ عبارة if-else كتلة عندما يكون الشرط صحيحًا، وأخرى عندما يكون خاطئًا - وهي أساس كل قرار يتخذه برنامجك. تلك هي الصفحة التالية.

الأسئلة الشائعة

ما هو تحويل الأنواع في Java؟

تحويل الأنواع هو تحويل قيمة من نوع بيانات إلى آخر. تُجري Java تحويلات "التوسيع" الصغيرة تلقائيًا (مثل التحويل من int إلى double)، لكن تحويل "التضييق" الذي قد يفقد بيانات (مثل التحويل من double إلى int) يتطلب تحويلًا صريحًا: int n = (int) 3.9;.

كيف تحوّل double إلى int في Java؟

ضع النوع الهدف بين قوسين قبل القيمة: int n = (int) 3.9;. هذا يقتطع باتجاه الصفر (يحذف الجزء العشري)، فتحصل على 3 وليس 4. وللتقريب بدلًا من ذلك، استخدم Math.round(3.9) الذي يُرجع 4.

كيف تحوّل String إلى int في Java؟

ليس String رقمًا، لذا لا يمكنك تحويله باستخدام (int). استخدم Integer.parseInt("42") للحصول على int، أو Double.parseDouble("3.14") للحصول على double. وإذا لم يكن النص رقمًا صالحًا، فإن هاتين الدالتين تطلقان استثناء NumberFormatException.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن