التوابع الجنيسة (Generic Methods)
التوابع الجنيسة (Generic Methods)
في الدرس السابق رأيت كيف تجعل صنفًا كاملًا جنيسًا. لكن أحيانًا تحتاج فقط إلى تابع واحد يكون جنيسًا — بينما يبقى باقي الصنف محدّد النوع. تتيح لك Java الإعلان عن معاملات نوع مباشرةً على التابع، بمعزل عن كون الصنف المحيط جنيسًا أم لا. يمنحك ذلك أدوات مساعدة خفيفة وقابلة لإعادة الاستخدام دون الالتزام بصنف جنيس كامل.
الصياغة: أين تُوضع معاملات النوع
تأتي قائمة معاملات النوع بين المُعدِّلات ونوع القيمة المُعادة:
تحليل الصياغة:
<T>— يُعلن عن معامل النوع لهذا التابع فحسب.Tالأولى بعد<T>هي نوع القيمة المُعادة.- المعامل
T valueيستخدم النوع ذاته.
يمكنك أن تملك معاملات نوع متعددة:
استنتاج النوع: المُصرِّف يؤدي العمل
لا تكاد تحتاج إلى تحديد وسيط النوع صراحةً عند استدعاء تابع جنيس — فالمُصرِّف يستنتجه من الوسيط الذي تمرّره:
identity("hello") الوسيط من نوع String فيكون T = String. في identity(42) النوع المعبَّأ هو Integer فيكون T = Integer. إن تعارضت الوسيطات وسَّع المُصرِّف النوع إلى أب مشترك (أو Object كملاذ أخير).
مثال عملي: تابع تبادل جنيس
افترض أنك تريد تبادل عنصرين في قائمة. بدون الجنيسية ستكتب تابعًا لكل نوع. بالتابع الجنيس تكتبه مرة واحدة:
java.util.Collections مليء بها — فـsort وbinarySearch وunmodifiableList كلها توابع جنيسة ساكنة.
إعادة نوع جنيس
يستطيع التابع الجنيس إنتاج قيمة جديدة لا مجرد العمل على وسيطاته. نمط شائع هو المصنع أو مساعد التحويل:
يستنتج المُصرِّف T من نوع الهدف في جانب الإسناد. يُسمّى ذلك استنتاج النوع الهدفي وقد تعزّز في Java 8.
التوابع الجنيسة داخل الأصناف الجنيسة
يمكن للتابع الجنيس أن يتواجد داخل صنف جنيس، ومعامل نوعه مستقل تمامًا عن معامل نوع الصنف:
Box<T> يُثبَّت T عند إنشاء نسخة من Box. أما U فيُستنتج من جديد في كل استدعاء لـmap. يعيش كل من المعاملين في نطاق مختلف ولا يتعارضان.
متى تستخدم تابعًا جنيسًا مقابل صنف جنيس
- استخدم تابعًا جنيسًا حين تكون علاقة النوع محلية لعملية واحدة — ولا داعي لتذكّرها بين الاستدعاءات.
- استخدم صنفًا جنيسًا حين يكون النوع جزءًا من هوية الكائن ويجب أن يبقى ثابتًا عبر استدعاءات متعددة (كـ
Stack<T>الذي يحتفظ بنوع ما بداخله).
<T> وأعلنت بالخطأ public <T> void foo(T x) على تابع ما، فإن T الخاصة بالتابع تُخفي T الخاصة بالصنف بصمت. ستُحذّرك معظم بيئات التطوير المتكاملة. استخدم حرفًا مختلفًا (مثل U) لمعاملات النوع على مستوى التابع داخل الأصناف الجنيسة.
الخلاصة
تتيح لك التوابع الجنيسة كتابة خوارزمية واحدة آمنة على مستوى الأنواع تعمل مع أنواع متعددة، دون جعل الصنف كله جنيسًا. تُعلن معامل النوع قبيل نوع القيمة المُعادة مباشرةً، ويستنتجه المُصرِّف من الوسيطات أو هدف الإسناد. هذا النمط موجود في كل مكان في المكتبة القياسية وفي أصناف الأدوات المُصمَّمة بعناية.