التأمل والاستبطان في Java: سحر متاح للجميع
\n\nتخيل أنك مبرمج تكتب كودًا قادرًا على تحليل نفسه بنفسه أثناء وقت التشغيل. يبدو وكأنه خيال علمي؟ في Java هذه حقيقة، وتسمى التأمل (Reflection).
\n\nعندما واجهت التأمل في Java لأول مرة، أذهلتني قوته. تخيل: يمكنك تحميل فئة باسمها، ومعرفة جميع دوالها وحقولها، وحتى استدعاء دالة خاصة أراد مؤلف الفئة إخفاءها. هذا يشبه الحصول على مفتاح لجميع الأبواب في المبنى. رائع؟ بالتأكيد. خطير؟ أيضًا نعم.
\n\nفي هذه المقالة، سنشرح ما هو التأمل والاستبطان في Java، وكيف يعملان، والأهم من ذلك - كيفية استخدامهما بحكمة. سيكون هناك الكثير من الكود والأمثلة والنصائح العملية. هيا بنا!
\n\nما هو التأمل في Java بكلمات بسيطة
\n\nالتأمل في Java هو آلية تسمح للبرنامج بالحصول على معلومات حول الفئات والواجهات والدوال والحقول أثناء التنفيذ. علاوة على ذلك، باستخدام التأمل يمكنك إنشاء كائنات، واستدعاء دوال، وتغيير قيم الحقول، حتى لو كانت خاصة.
\n\nوما هو الاستبطان في Java؟ هو جزء من التأمل مسؤول تحديدًا عن "التلصص": الحصول على معلومات حول بنية الفئة دون تغييرها. الاستبطان هو تحليل، والتأمل هو تحليل + فعل.
\n\nفي الأساس، يوجد الفئة java.lang.Class. إنها بمثابة "جواز سفر" لأي كائن. عندما تقوم JVM بتحميل فئة، تنشئ كائن Class يخزن جميع المعلومات الوصفية.
كيفية الحصول على كائن Class: ثلاث طرق
\n\nقبل أن نبدأ في السحر بالتأمل، نحتاج إلى الحصول على كائن Class. إليك ثلاث طرق رئيسية:
// 1. عبر .class\nClass<String> stringClass = String.class;\n\n// 2. عبر getClass() من كائن\nString hello = "مرحباً";\nClass<? extends String> helloClass = hello.getClass();\n\n// 3. عبر Class.forName() (الأكثر مرونة)\ntry {\n Class<?> dynamicClass = Class.forName("java.util.ArrayList");\n} catch (ClassNotFoundException e) {\n e.printStackTrace();\n}\n\n\nالطريقة الثالثة مفيدة بشكل خاص عندما يكون اسم الفئة غير معروف في وقت الترجمة - على سبيل المثال، يأتي من ملف إعدادات أو قاعدة بيانات.
\n\nالاستبطان: ننظر داخل الفئة
\n\nلنكتب فئة صغيرة ونرى ما يمكننا معرفته عنها باستخدام الاستبطان في Java.
\n\nimport java.lang.reflect.*;\n\npublic class ReflectionDemo {\n \n private String secret = "هذا سر!";\n public int number = 42;\n \n public void publicMethod() {\n System.out.println("دالة عامة");\n }\n \n private void privateMethod() {\n System.out.println("دالة خاصة");\n }\n \n public static void main(String[] args) throws Exception {\n // نحصل على كائن Class\n Class<?> demoClass = Class.forName("ReflectionDemo");\n \n System.out.println("=== اسم الفئة ===");\n System.out.println(demoClass.getName());\n \n System.out.println("\\n=== جميع الحقول ===");\n Field[] fields = demoClass.getDeclaredFields();\n for (Field field : fields) {\n System.out.println(field.getName() + " : " + field.getType().getSimpleName());\n }\n \n System.out.println("\\n=== جميع الدوال ===");\n Method[] methods = demoClass.getDeclaredMethods();\n for (Method method : methods) {\n System.out.println(method.getName() + "()");\n }\n \n System.out.println("\\n=== المنشئات ===");\n Constructor<?>[] constructors = demoClass.getDeclaredConstructors();\n for (Constructor<?> constructor : constructors) {\n System.out.println(constructor);\n }\n }\n}\n\n\nعند تشغيل هذا