أساسيات جافا

الثوابت، final وأعراف التسمية

15 دقيقة الدرس 7 من 14

الثوابت، final وأعراف التسمية

في كل برنامج توجد قيم يجب ألا تتغير بعد تعيينها — عدد ساعات اليوم، أو معدل الضريبة، أو الحد الأقصى لعدد المحاولات. تمنحك Java الكلمة المحجوزة final لتقفل متغيرًا بحيث لا يمكن إعادة تعيين قيمته. إذا جمعت final مع المُعدِّل static حصلت على ثابت حقيقي على مستوى الصنف. علاوة على ذلك، تتبع مجتمع Java مجموعة صارمة من أعراف التسمية التي تُخبر كل قارئ فورًا بنوع المعرّف الذي ينظر إليه. كلا الموضوعين قواعد بسيطة ذات أثر كبير على جودة الكود.

الكلمة المحجوزة final

تعني إضافة final إلى متغير محلي أو حقل أنه يمكن تعيينه مرة واحدة فقط. أي محاولة لإعادة التعيين تُسبب خطأ في وقت الترجمة، فيكتشف المُصرِّف الخطأ قبل أن يعمل البرنامج.

public class FinalDemo { public static void main(String[] args) { final int MAX_RETRIES = 3; // MAX_RETRIES = 5; // خطأ في الترجمة: لا يمكن إعادة تعيين متغير final System.out.println("Max retries allowed: " + MAX_RETRIES); } }
final لا تعني أن الكائن غير قابل للتعديل. عندما تُضيف final إلى مرجع كائن، لا يمكن للمرجع أن يشير إلى كائن آخر — لكن الكائن نفسه لا يزال قابلًا للتعديل. مثلًا، قائمة final List<String> لا يمكن إعادة تعيينها لقائمة جديدة، لكن يمكنك استدعاء add() عليها.

الثوابت على مستوى الصنف باستخدام static final

المتغير المحلي المعرَّف بـ final لا يُفيد إلا داخل دالة واحدة. لمشاركة ثابت عبر البرنامج بأكمله، أعلنه بصيغة public static final على مستوى الصنف. static تعني أنه ينتمي للصنف نفسه لا لأي كائن، فيُنشأ مرة واحدة ويُستخدم في كل مكان.

public class MathConstants { public static final double PI = 3.14159265358979; public static final int DAYS_IN_WEEK = 7; public static final String APP_VERSION = "1.0.0"; public static void main(String[] args) { double radius = 5.0; double area = MathConstants.PI * radius * radius; System.out.println("Circle area: " + area); } }

يُشير الكود الخارجي إلى ثابت عام بالصيغة اسمالصنف.اسمالثابت، أو مباشرةً بـ اسمالثابت من داخل نفس الصنف.

تسمية الثوابت: UPPER_SNAKE_CASE

العُرف في Java هو كتابة حقول static final بأسلوب UPPER_SNAKE_CASE — أحرف كبيرة كلها تفصل بينها شرطات سفلية. هذه إشارة بصرية تدل على أن القيمة ثابتة لا تتغير.

  • MAX_CONNECTIONS — صحيح
  • TAX_RATE — صحيح
  • defaultTimeout — خطأ (يبدو كمتغير عادي)
  • MAXCONNECTIONS — خطأ (صعب القراءة بدون فواصل)
عند الشك، استخرج ثابتًا. إذا كتبت الرقم أو النص الحرفي نفسه أكثر من مرة، استخرجه إلى ثابت static final مُسمًّى. قراءة MAX_LOGIN_ATTEMPTS أوضح بكثير من قراءة الرقم الحرفي 5 المتناثر في الكود.

نظرة عامة على أعراف التسمية في Java

يتبع مجتمع Java نظام تسمية موحدًا واحدًا. تعلّم هذه القواعد مرة واحدة وسيبدو كودك احترافيًا لأي مطور Java يقرأه.

الأصناف والواجهات — PascalCase

كل كلمة تبدأ بحرف كبير بلا فواصل. أصناف بالأسماء وواجهات بالصفات.

class BankAccount { } // صنف — اسم، PascalCase class HttpRequestHandler { } // صنف — اسم مركب interface Runnable { } // واجهة — صفة، PascalCase interface Comparable { }

الدوال والمتغيرات — camelCase

تبدأ بحرف صغير وكل كلمة لاحقة بحرف كبير. الدوال عبارات فعلية والمتغيرات عبارات اسمية.

int accountBalance = 1000; // متغير — camelCase اسم String firstName = "Alice"; void calculateInterest() { } // دالة — camelCase عبارة فعلية boolean isAccountActive() { } // دوال منطقية تبدأ بـ is/has/can

الحزم — أحرف صغيرة كليًا

أسماء الحزم كلها أحرف صغيرة، وعادةً اسم النطاق معكوسًا تفصل بين أجزائه نقاط. لا camelCase ولا شرطات سفلية.

package com.mycompany.banking.accounts; package org.example.utils;

الثوابت — UPPER_SNAKE_CASE

كما ذُكر سابقًا، حقول static final تُكتب بأحرف كبيرة مع شرطات سفلية. هذه الحالة الوحيدة في Java التي تظهر فيها الشرطات السفلية في الأسماء.

public static final int MAX_CONNECTIONS = 100; public static final double TAX_RATE = 0.08; public static final String DEFAULT_CHARSET = "UTF-8";

تطبيق كل شيء معًا

الصنف التالي يستخدم كل عرف بشكل صحيح:

package com.example.shop; // حزمة بأحرف صغيرة public class ShoppingCart { // صنف PascalCase public static final double MAX_DISCOUNT = 0.50; // ثابت UPPER_SNAKE public static final int MAX_ITEMS = 100; private String customerName; // متغير camelCase private int itemCount; public ShoppingCart(String customerName) { // معامل camelCase this.customerName = customerName; this.itemCount = 0; } public void addItem() { // دالة فعلية camelCase if (itemCount < MAX_ITEMS) { itemCount++; } } public boolean isEmpty() { // دالة منطقية بادئة is return itemCount == 0; } public int getItemCount() { // getter بادئة get return itemCount; } }
لا تخلط بين الأعراف. كتابة Max_Discount أو maxDiscount لثابت، أو shopping_cart لاسم صنف، يُشير لكل قارئ Java أن شيئًا ما غير صحيح. أدوات تحليل الكود الساكن مثل Checkstyle تكتشف انتهاكات الأعراف تلقائيًا — التزم بها من البداية.

مرجع سريع

  • الأصناف / الواجهاتPascalCaseBankAccount، Serializable
  • الدوال / المتغيراتcamelCasecalculateTax()، totalAmount
  • الثوابت (static final)UPPER_SNAKE_CASEMAX_SIZE، PI
  • الحزمall.lowercase.dotscom.example.util

الخلاصة

استخدم final لمنع إعادة تعيين متغير وإيصال النية للقراء المستقبليين. استخدم public static final لإنشاء ثابت مشترك على مستوى الصنف. سمِّ تلك الثوابت بـ UPPER_SNAKE_CASE، وسمِّ الأصناف بـ PascalCase، وسمِّ كل شيء آخر بـ camelCase. هذه الأعراف ليست تفضيلات أسلوبية اختيارية — إنها المعيار الذي تتبعه كل قاعدة كود Java، وانتهاكها علامة واضحة للمطورين على أن شيئًا ما لا ينتمي إلى هذا المكان.