0Pricing
Java Academy · درس

الحقول والثوابت الثابتة

استخدم الحقول الثابتة للحالة المشتركة، والثوابت باستخدام static final، والمهيئات الثابتة

الحقول والثوابت الثابتة درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

الحقول الساكنة والثوابت

تنتمي الحقول الساكنة إلى الصنف، لا إلى المثيلات. وتكون مشتركة بين جميع كائنات الصنف. وتجمع الثوابت بين static وfinal لإنشاء قيم غير قابلة للتغيير على مستوى الصنف.

الحقول الساكنة مقارنةً بحقوق المثيلات

يملك حقل المثيل نسخة منفصلة لكل كائن، بينما يملك الحقل الساكن نسخة واحدة مشتركة بين جميع كائنات الصنف.

class Counter {
    private static int totalCount = 0;  // shared across all instances
    private int instanceId;              // unique per instance

    Counter() {
        totalCount++;
        instanceId = totalCount;
    }

    static int getTotalCount() { return totalCount; }
    int getInstanceId()        { return instanceId; }
}

Counter c1 = new Counter();
Counter c2 = new Counter();
Counter c3 = new Counter();

System.out.println(Counter.getTotalCount()); // 3
System.out.println(c1.getInstanceId());       // 1
System.out.println(c3.getInstanceId());       // 3

الثوابت باستخدام static final

عرّف الثوابت باستخدام public static final. ووفقًا للعرف، تُكتب أسماؤها بصيغة SCREAMING_SNAKE_CASE.

class MathConstants {
    public static final double PI      = 3.141592653589793;
    public static final double E       = 2.718281828459045;
    public static final double GOLDEN  = 1.618033988749895;
    public static final int    PRIMES[] = {2, 3, 5, 7, 11, 13};
}

// Access without an instance
System.out.println(MathConstants.PI);

// Constants on domain classes
class HttpStatus {
    public static final int OK        = 200;
    public static final int NOT_FOUND = 404;
    public static final int SERVER_ERR = 500;
}

كتل التهيئة الساكنة

عندما يتطلب ثابت تهيئة معقدة، استخدم كتلة تهيئة ساكنة تُنفَّذ مرة واحدة عند تحميل الصنف.

import java.util.*;

class Config {
    public static final Map<String, String> DEFAULTS;

    static {
        Map<String, String> map = new HashMap<>();
        map.put("timeout",  "30");
        map.put("maxRetry", "3");
        map.put("logLevel", "INFO");
        DEFAULTS = Collections.unmodifiableMap(map);
    }
}

System.out.println(Config.DEFAULTS.get("timeout")); // 30

نمط العداد الساكن

تُستخدم الحقول الساكنة عادةً لإنشاء المعرّفات، أو عدّ المقاييس، أو إنشاء ذاكرات تخزين مؤقت مشتركة.

import java.util.concurrent.atomic.AtomicLong;

class Order {
    private static final AtomicLong ID_SEQUENCE = new AtomicLong(1000);

    private final long id;
    private final String item;

    Order(String item) {
        this.id   = ID_SEQUENCE.getAndIncrement();
        this.item = item;
    }

    long getId()   { return id; }
    String getItem() { return item; }
}

Order o1 = new Order("Laptop");
Order o2 = new Order("Mouse");
System.out.println(o1.getId()); // 1000
System.out.println(o2.getId()); // 1001

Singleton باستخدام حقل ساكن

يحتفظ حقل ساكن بالمثيل الوحيد في Singleton. استخدم التهيئة الكسولة للأصناف التي قد لا تكون مطلوبة دائمًا.

class DatabasePool {
    private static volatile DatabasePool instance;
    private final int maxConnections;

    private DatabasePool() { this.maxConnections = 20; }

    public static DatabasePool getInstance() {
        if (instance == null) {
            synchronized (DatabasePool.class) {
                if (instance == null)
                    instance = new DatabasePool();
            }
        }
        return instance;
    }

    public int getMaxConnections() { return maxConnections; }
}

System.out.println(DatabasePool.getInstance().getMaxConnections()); // 20

الاستيراد الساكن

يتيح لك import static استخدام الأعضاء الساكنة دون بادئة اسم الصنف — وهو مفيد للثوابت وأساليب الأدوات.

import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
import static java.lang.Math.pow;

// Without import static: Math.PI * Math.pow(r, 2)
double radius = 5.0;
double area = PI * pow(radius, 2);
System.out.printf("Area: %.2f%n", area); // 78.54

// Caution: overuse of static imports hurts readability
// Acceptable for: Math.*, Assert.* in tests, TimeUnit

سلامة الخيوط في الحقول الساكنة

تتطلب الحقول الساكنة المشتركة بين الخيوط مزامنة أو أنواعًا ذرية لتجنّب حالات التسابق.

import java.util.concurrent.atomic.*;

class RequestMetrics {
    private static final AtomicLong requestCount  = new AtomicLong(0);
    private static final AtomicLong totalLatencyMs = new AtomicLong(0);

    public static void record(long latencyMs) {
        requestCount.incrementAndGet();
        totalLatencyMs.addAndGet(latencyMs);
    }

    public static double averageLatency() {
        long count = requestCount.get();
        return count == 0 ? 0 : (double) totalLatencyMs.get() / count;
    }
}
RequestMetrics.record(45);
RequestMetrics.record(120);
System.out.println(RequestMetrics.averageLatency()); // 82.5

مخاطر الحقول الساكنة القابلة للتغيير

الحقول الساكنة القابلة للتغيير خطرة: فالحالة العامة القابلة للتغيير يصعب اختبارها، ولا تكون آمنة للخيوط دون عناية، كما تنشئ اقترانًا خفيًا بين الأصناف.

// BAD: mutable static state
class GlobalConfig {
    public static String environment = "dev"; // mutable global!
}
// Any code anywhere can change GlobalConfig.environment
// Very hard to test, unexpected interactions

// BETTER: immutable constant
class GlobalConfig2 {
    public static final String ENVIRONMENT =
        System.getenv().getOrDefault("APP_ENV", "dev");
}

// BEST: inject via constructor (dependency injection)
class Service {
    private final String environment;
    Service(String environment) { this.environment = environment; }
}

نمط واجهة الثوابت المضاد

لا يُنصح باستخدام واجهة للاحتفاظ بالثوابت (وهو نمط "واجهة الثوابت" المضاد). استخدم بدلًا منها صنفًا ذا مُنشئ خاص.

// BAD: constant interface — pollutes the namespace of implementing classes
interface FinancialConstants {
    double TAX_RATE = 0.08;  // implicitly public static final
}

// GOOD: utility class for constants
final class FinancialConstants2 {
    private FinancialConstants2() {} // prevent instantiation

    public static final double TAX_RATE  = 0.08;
    public static final double VAT_RATE  = 0.20;
    public static final int    MAX_ITEMS = 100;
}
System.out.println(FinancialConstants2.TAX_RATE); // 0.08

تطبيقي: مفاتيح الميزات باستخدام الثوابت

استخدام ثوابت منطقية static final كمفاتيح ميزات وقت الترجمة — إذ يزيل مترجم JIT الفروع غير المستخدمة.

class Features {
    public static final boolean ENABLE_ANALYTICS   = true;
    public static final boolean ENABLE_AI_SEARCH    = false;
    public static final boolean DEBUG_MODE          =
        "true".equals(System.getenv("DEBUG"));
}

// The JIT eliminates this if-block when ENABLE_AI_SEARCH is false:
if (Features.ENABLE_AI_SEARCH) {
    System.out.println("Running AI search...");
}

if (Features.DEBUG_MODE) {
    System.out.println("[DEBUG] Request received");
}

تحقق سريع

ما الفرق بين الحقل الساكن وحقل المثيل؟

مراجعة: الحقول الساكنة والثوابت

أهم النقاط:

  • تنتمي الحقول الساكنة إلى الصنف — نسخة واحدة مشتركة بين جميع المثيلات
  • الثوابت: public static final UPPER_SNAKE_CASE
  • استخدم كتل التهيئة الساكنة للثوابت التي تتطلب تهيئة معقدة
  • فضّل AtomicLong/AtomicInteger للحقول الساكنة القابلة للتغيير في الشيفرة المتزامنة
  • تجنّب الحقول الساكنة القابلة للتغيير — فهي تنشئ حالة عامة خفية يصعب اختبارها
  • استخدم صنفًا غير قابل للإنشاء (بمُنشئ خاص) للثوابت بدلًا من الواجهة

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

هل درس «الحقول والثوابت الثابتة» مجاني؟

نعم — نص درس «الحقول والثوابت الثابتة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «الحقول والثوابت الثابتة»؟

استخدم الحقول الثابتة للحالة المشتركة، والثوابت باستخدام static final، والمهيئات الثابتة تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «الحقول والثوابت الثابتة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. قواعد تحميل الأساليب الزائد
  2. معاملات Varargs
  3. الحقول والثوابت الثابتة
  4. فئات الأدوات وأساليب المصنع الثابتة
← العودة إلى Java Academy