عامل :: (Double Colon) في Java 8: من المبتدئ إلى المحترف
\n\nهل سبق لك أن كتبت كودًا في Java 8 ورأيت بنية غريبة مثل System.out::println أو String::length؟ تبدو وكأنها سحر، أليس كذلك؟ في الواقع، هذا ليس سحرًا، بل هو أحد أكثر الأدوات أناقة في Java الحديثة — عامل النقطتان الرأسيتان (المعروف أيضًا باسم double colon operator أو مرجع الطريقة).
في هذه المقالة، سنشرح عامل :: من الأساسيات إلى التقنيات المتقدمة. ستتعلم كتابة كود أكثر نظافة وإيجازًا وقابلية للقراءة. هيا بنا!
ما هو عامل :: ولماذا هو مطلوب؟
\n\nتم تقديم عامل :: (double colon) في Java 8 كسكر نحوي لتعبيرات لامدا. إذا كان تعبير لامدا يقوم ببساطة باستدعاء طريقة موجودة، يمكنك استبداله بمرجع طريقة. وهذا يجعل الكود أقصر وأكثر تعبيرًا.
قارن بنفسك:
\n\n// تعبير لامدا\nlist.forEach(s -> System.out.println(s));\n\n// مرجع طريقة (عامل ::)\nlist.forEach(System.out::println);\n\nالخيار الثاني ليس فقط أقصر، بل يخبرك فورًا: "لكل عنصر، استدعِ طريقة println من System.out". روعة!
\n\nأربعة أنواع من مراجع الطرق
\n\nفي Java 8، هناك أربعة أنواع رئيسية من method reference. دعنا نشرح كل نوع مع أمثلة.
\n\n1. مرجع طريقة ثابتة
\n\nالصيغة: ClassName::staticMethodName
مثال: حساب عدد الأرقام الزوجية في قائمة.
\n\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class StaticMethodReference {\n public static boolean isEven(Integer number) {\n return number % 2 == 0;\n }\n\n public static void main(String[] args) {\n List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);\n \n // لامدا\n long countLambda = numbers.stream()\n .filter(n -> StaticMethodReference.isEven(n))\n .count();\n \n // مرجع طريقة ثابتة\n long countRef = numbers.stream()\n .filter(StaticMethodReference::isEven)\n .count();\n \n System.out.println("عدد الأرقام الزوجية: " + countRef); // 3\n }\n}\n\nلاحظ: نحن لا نستدعي طريقة isEven — نحن فقط نمرر مرجعًا إليها. Java نفسها ستضع كل عنصر من القائمة كوسيطة.
2. مرجع طريقة مثيل لكائن محدد
\n\nالصيغة: objectReference::instanceMethodName
يُستخدم هذا النوع عندما يكون لديك كائن محدد بالفعل وتريد استدعاء طريقته.
\n\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class InstanceMethodReference {\n public static void main(String[] args) {\n List<String> names = Arrays.asList("آنا", "بوريس", "فيكتور");\n \n // إنشاء كائن StringBuilder\n StringBuilder sb = new StringBuilder("الأسماء: ");\n \n // لامدا\n names.forEach(name -> sb.append(name).append(" "));\n \n // مرجع طريقة مثيل\n // (لكن append يُرجع StringBuilder، لذا نستخدم لامدا)\n // أما بالنسبة لـ System.out.println - فهو مثالي:\n names.forEach(System.out::println);\n \n System.out.println(sb.toString()); // الأسماء: آنا بوريس فيكتور\n }\n}\n\nالمثال الكلاسيكي هو System.out::println. System.out هو كائن محدد من نوع PrintStream، و println هي طريقته.
3. مرجع طريقة مثيل لكائن عشوائي من نوع معين
\n\nالصيغة: ClassName::instanceMethodName
غالبًا ما يُخلط هذا النوع مع النوع السابق. هنا لا نحدد كائنًا محددًا — بدلاً من ذلك، نقول: "خذ أي كائن من هذه الفئة واستدعِ طريقته".
\n\nالمدونات
توصيات الكتب
اقرأ أيضًا