Generics في Java: لماذا هي ضرورية وكيفية استخدامها للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

Generics في Java: لماذا هي ضرورية وكيفية استخدامها للمبتدئين

\n\n

إذا كنت قد بدأت للتو في تعلم Java، فستواجه عاجلاً أم آجلاً مفهوم Generics (الأنواع العامة أو الجينيريكس). هذه الميزة القوية في اللغة تتيح لك كتابة كود أكثر مرونة وأماناً وقابلية لإعادة الاستخدام. في هذه المقالة، سنشرح بكلمات بسيطة ما هي Generics، ولماذا هي ضرورية وكيفية تطبيقها عملياً.

\n\n

ما هي Generics في Java؟

\n\n

Generics (من الكلمة الإنجليزية "generic" — عام، جنسي) هي آلية في Java تسمح بإنشاء كلاسات وواجهات ودوال تعمل مع أنواع بيانات مختلفة، مع ضمان فحص صارم للأنواع في مرحلة الترجمة (Compilation).

\n\n

ببساطة، تسمح لك الجينيريكس بتحديد: "هذه الكلاس أو الدالة ستعمل مع أي نوع بيانات، لكنني لا أعرف بعد أي نوع بالضبط". يتم تحديد النوع لاحقاً، عند إنشاء كائن أو استدعاء دالة.

\n\n

المشكلة بدون Generics

\n\n

قبل ظهور Generics (في Java 5)، كان المطورون يستخدمون تحويل الأنواع (Casting) ويعملون مع Object. كان هذا غير مريح وخطير:

\n\n
// بدون Generics (الطريقة القديمة)\nList list = new ArrayList();\nlist.add("مرحباً");\nlist.add(123); // خطأ؟ لا، المترجم سيمرره\n\nString text = (String) list.get(0); // التحويل إجباري\n// String num = (String) list.get(1); // ClassCastException أثناء التنفيذ!
\n\n

هنا لا يرى المترجم الخطأ، لكن البرنامج سيتعطل أثناء التنفيذ. Generics تحل هذه المشكلة.

\n\n

لماذا نحتاج Generics في Java؟

\n\n

تقدم Generics ثلاث مزايا رئيسية:

\n\n
    \n
  • أمان الأنواع (Type Safety) — يتم اكتشاف الأخطاء في مرحلة الترجمة، وليس أثناء تنفيذ البرنامج.
  • \n
  • الاستغناء عن التحويل الصريح (No Casting) — لا حاجة لكتابة (String) في كل مرة.
  • \n
  • إعادة استخدام الكود (Code Reuse) — كلاس أو دالة واحدة يمكن أن تعمل مع أنواع مختلفة.
  • \n
\n\n

مثال مع Generics

\n\n

شاهد كيف يتغير الكود باستخدام الجينيريكس:

\n\n
// مع Generics\nList<String> list = new ArrayList<>();\nlist.add("مرحباً");\n// list.add(123); // خطأ في الترجمة! لا يمكن إضافة Integer\n\nString text = list.get(0); // لا حاجة للتحويل\n// المترجم يعرف بالفعل أنها String
\n\n

أصبح الكود أبسط وأكثر أماناً وأسهل للقراءة.

\n\n

كيفية استخدام Generics: الهياكل الأساسية

\n\n

دعنا نستعرض ثلاث طرق رئيسية لتطبيق الجينيريكس: في الكلاسات، والدوال، والواجهات.

\n\n

1. كلاسات Generic

\n\n

يمكنك إنشاء كلاس يعمل مع أي نوع. للقيام بذلك، بعد اسم الكلاس بين قوسين زاوية، يتم تحديد معامل النوع (عادةً T، E، K، V):

\n\n
// كلاس عام "صندوق"\npublic class Box<T> {\n    private T content;\n\n    public void put(T item) {\n        this.content = item;\n    }\n\n    public T get() {\n        return content;\n    }\n}\n\n// الاستخدام\nBox<String> stringBox = new Box<>();\nstringBox.put("كتاب");\nString book = stringBox.get(); // بدون تحويل\n\nBox<Integer> intBox = new Box<>();\nintBox.put(42);\nint number = intBox.get();
\n\n

2. دوال Generic

\n\n

يمكن جعل دالة واحدة فقط عامة، وليس الكلاس بأكمله. هذا مفيد عندما تحتاج الدالة إلى معالجة أنواع مختلفة بغض النظر عن الكلاس:

\n\n
public class Utils {\n    // دالة عامة\n    public static <T> void printArray(T[] array) {\n        for (T element : array) {\n            System.out.print(element + " ");\n        }\n        System.out.println();\n    }\n}\n\n// الاستدعاء\nInteger[] intArray = {1, 2, 3};\nString[] strArray = {"A", "B", "C"};\n\nUtils.printArray(intArray); // 1 2 3\nUtils.printArray(strArray); // A B C
\n\n

3. واجهات Generic

\n\n

الواجهة

المدونات

توصيات الكتب