static في Java
ماذا تعني static؟ ولماذا ترتبط بالكلاس لا بالكائن؟ وكيف نستخدم static variables و static methods بشكل صحيح؟
ما معنى static؟
عندما تنشئ Object من Class، لكل كائن نسخته الخاصة من البيانات — شخصان، لكل واحد اسم وعمر مختلفان.
لكن أحيانًا نحتاج قيمة أو دالة مشتركة بين جميع الكائنات، لا تخص كائناً واحداً. هنا تأتي static.
👤 بدون static (خاص بكل كائن)
- •كل Object له نسخته الخاصة
- •الوصول عبر:
p1.name - •مثل: اسم الشخص، عمره، عنوانه
🏢 مع static (مشترك للجميع)
- •قيمة واحدة لجميع الكائنات
- •الوصول عبر:
Counter.count - •مثل: عداد الكائنات، اسم الشركة
المتغير static — قيمة مشتركة بين جميع الكائنات
سننشئ كلاساً فيه عدّاد static يُحسب كم كائناً تم إنشاؤه:
class Counter { // متغير static — مشترك لجميع الكائنات public static int count = 0; // Constructor — يزيد العداد عند كل إنشاء Counter() { count++; } } // إنشاء ثلاثة كائنات Counter a = new Counter(); ← count = 1 Counter b = new Counter(); ← count = 2 Counter c = new Counter(); ← count = 3 System.out.println(Counter.count); ← 3
3
🔍 ماذا يحدث في الذاكرة؟
| بعد | الكائن | Counter.count (مشترك) |
|---|---|---|
| البداية | — | 0 |
| new Counter() | a | 1 |
| new Counter() | b | 2 |
| new Counter() | c | 3 |
لاحظ أن count لا يتكرر — هو نسخة واحدة مشتركة تزيد في كل مرة.
الدالة static — لا تحتاج إنشاء Object
الدوال التي لا تعتمد على بيانات كائن معيّن — مثل الدوال الرياضية — يُفضَّل جعلها static. يمكن استدعاؤها مباشرةً باسم الكلاس بدون إنشاء Object.
class MathUtil { public static int add(int a, int b) { return a + b; } public static int max(int a, int b) { return (a > b) ? a : b; } public static double circleArea(double r) { return 3.14159 * r * r; } }
System.out.println(MathUtil.add(5, 3)); ← 8 System.out.println(MathUtil.max(10, 7)); ← 10 System.out.println(MathUtil.circleArea(5)); ← 78.53975
8 10 78.53975
مكتبة Java الشهيرة Math تعمل بنفس الطريقة — Math.sqrt(16) و Math.abs(-5) كلها دوال static تستدعيها مباشرةً!
متى أستخدم static ومتى لا أستخدمه؟
| الحالة | استخدم | مثال |
|---|---|---|
| قيمة مشتركة بين جميع الكائنات | static |
عداد الكائنات، اسم الشركة |
| دالة لا تعتمد على بيانات كائن | static |
MathUtil.add(), Math.sqrt() |
| بيانات تختلف من كائن لآخر | بدون static |
اسم الشخص، عمره، راتبه |
| دالة تعتمد على خصائص الكائن | بدون static |
getName(), getAge() |
⚠️ تحذير: لا تجعل كل شيء static!
بعض المبتدئين يضعون static على كل متغير ودالة لتجنب بعض الأخطاء — هذا يُفسد تصميم البرنامج ويلغي فكرة الكائنات:
❌ خطأ في التصميم
class Person {
static String name;
}
كل الأشخاص سيشتركون في نفس الاسم!
✅ صحيح
class Person {
String name;
}
لكل شخص اسمه الخاص
قاعدة مهمة — static لا تستطيع رؤية non-static
داخل دالة static (مثل main) لا يمكنك استخدام متغيرات غير static مباشرة. السبب: المتغيرات غير static تحتاج كائناً لتوجد، بينما static موجودة قبل أي كائن.
class Test { int x = 10; ← متغير عادي (non-static) public static void main(String[] args) { // خطأ: x غير static — لا يمكن الوصول إليها من static System.out.println(x); ← ERROR! // الحل: إنشاء كائن أولًا Test t = new Test(); System.out.println(t.x); ← 10 ✅ } }
🔍 لماذا؟ — شرح مبسّط
main أولاً قبل أي شيء — وهي static تعمل بدون كائن.
x غير static — يعني يوجد فقط داخل كائن.
x تقصد!
t.x.
هذا يفسّر لماذا كنا نكتب public static void أمام كل دوالنا في main — لأن main نفسها static وتحتاج كل ما تستدعيه أن يكون static أو عبر كائن.
أخطاء شائعة عند المبتدئين ⚠️
استخدام static في كل مكان
وضع static على متغيرات تختلف من كائن لآخر يجعل جميع الكائنات تتشارك نفس القيمة — وهذا خطأ منطقي خطير.
الوصول لمتغير static عبر كائن بدل الكلاس
⚠️ يعمل لكن مُضلِّل
Counter a = new Counter();
a.count; // يعمل لكن محيّر
✅ الأفضل
Counter.count;
واضح أنه تابع للكلاس
استخدام متغير non-static داخل دالة static مباشرةً
يجب دائماً إنشاء كائن أولاً للوصول للمتغيرات غير static من داخل static method.
📋 ملخص الدرس
static = تابع للكلاس، مشترك بين جميع الكائنات
الوصول: ClassName.member بدون كائن
static method لا ترى non-static مباشرةً
لا تستخدمها لكل شيء — فقط عند الحاجة الفعلية
⏭️ في الدرس القادم:
سنتعلم المصفوفات (Arrays) — كيف تخزّن مجموعة قيم داخل متغير واحد، والتعامل معها بالحلقات.