أساسيات Enum
أساسيات Enum
قبل وصول enums في Java 5، كان المطورون يُمثّلون مجموعةً ثابتة من الثوابت المترابطة باستخدام حقول public static final int — وهو ما يُعرف بنمط int enum. كان يؤدّي الغرض، لكنه هشّ: لم يمنع أحدًا من تمرير عدد صحيح اعتباطي حيث لا يجب قبول سوى قيم محدّدة، وكانت القيم تفتقر كليًا إلى سلامة الأنواع.
الكلمة المفتاحية enum تحلّ كل ذلك. فـ enum يُعلن نوعًا مُسمًّى لا تتجاوز قيمه القانونية مجموعةً ثابتة من الثوابت التي تُحدّدها مسبقًا. يُطبّق المُصرّف حينئذٍ أنّ هذا النوع لا يقبل إلا تلك القيم.
تعريف Enum
تُشبه صياغته تعريف الكلاس، لكنّه يستخدم كلمة enum:
كل مُعرِّف في الجسم — MONDAY وTUESDAY وما بعدها — هو ثابت من النوع Day. باتفاق، تُكتب ثوابت enum بأحرف كبيرة مفصولة بشرطة سفلية (UPPER_SNAKE_CASE)، تمامًا كسائر الثوابت في Java.
enum Day إلى كلاس يرث من java.lang.Enum<Day>. كل ثابت هو حقل public static final Day في ذلك الكلاس. هذا يعني أن enums يمكن أن تحتوي على بانيات وحقول وتوابع — وهذه مواضيع دروس لاحقة.
استخدام ثوابت Enum
تُشير إلى ثابت باسم النوع ونقطة، تمامًا كحقل ساكن:
name() يُعيد اسم الثابت كـString. وordinal() يُعيد موضعه (يبدأ من صفر) في ترتيب التعريف. كلاهما موروث من الكلاس الأساسي java.lang.Enum.
التكرار على جميع الثوابت
يحصل كل enum تلقائيًا على تابع ساكن values() يُعيد مصفوفة بجميع الثوابت بترتيب التعريف:
يوجد أيضًا تابع ساكن valueOf(String name) يُجري البحث العكسي:
valueOf يُلقي IllegalArgumentException إذا لم تُطابق السلسلة أيّ ثابت بالضبط (حساسة لحالة الأحرف).
Enums في switch
من أكثر استخدامات enum طبيعيةً جعلُها المُحدِّد في جملة switch. لأن المُصرّف يعرف كل قيمة ممكنة للـ enum، يمكنه تحذيرك عند نسيان حالة ما، والكود يقرأ بشكل واضح جدًا:
لاحظ أنّ داخل تسميات case تكتب اسم الثابت فقط — MONDAY لا Day.MONDAY. يعرف المُصرّف النوع مسبقًا من مُحدِّد switch.
أدخل Java 14+ switch expressions (تعابير switch) الأكثر أناقةً، والتي تُجبرك على تغطية كل حالة (أو توفير default):
صياغة السهم (->) تُلغي السقوط التلقائي (fall-through) والحاجة إلى break. عندما تُغطَّى كل الثوابت بلا default، يُطبّق المُصرّف الشمولية — إذا أضفت ثابتًا جديدًا للـ enum لاحقًا، سيرفض تعبير switch التصريف حتى تُعالج الحالة الجديدة. هذا ضمان أمان بالغ القوة.
المساواة والمقارنة
لأن كل ثابت هو singleton — كائن واحد فقط موجود لكل ثابت — يمكنك مقارنة قيم enum بأمان بـ== بدلًا من .equals():
ثوابت enum قابلة للمقارنة أيضًا (Comparable) بترتيبها الطبيعي وهو ترتيب التعريف، وهي Serializable تلقائيًا.
الخلاصة
تُحلّ Enums الأنماط الهشّة للثوابت بـمجموعة مُسمّاة آمنة الأنواع. الأفكار الأساسية للتذكّر: تُعرَّف بكلمة enum، وتُرجَع ثوابتها بـType.CONSTANT، وتتكرّر عليها بـvalues()، وتُحوَّل من سلسلة بـvalueOf()، وتُستخدم في switch للتفريع الواضح (ويُفضَّل شكل switch-expression للشمولية)، وتُقارَن بـ==. يُوسّع الدرس القادم enums بحقول وتوابع مخصّصة.