java - ماجستير - معنى كلمة عنوان بالانجليزي




ما هو التفكير ولماذا هو مفيد؟ (14)

الانعكاس هو قدرة اللغة على فحص الدرجات ، والطرق ، والسمات ، وغير ذلك بشكل ديناميكي في وقت التشغيل.

على سبيل المثال ، تحتوي جميع الكائنات في Java على الطريقة getClass() ، والتي تتيح لك تحديد فئة الكائن حتى إذا كنت لا تعرفها في وقت التحويل البرمجي (على سبيل المثال إذا كنت قد أعلنتها ككائن) - قد يبدو هذا تافهاً ، ولكن مثل التأمل غير ممكن في لغات أقل ديناميكية مثل C++ . تتيح لك الاستخدامات الأكثر تقدمًا سرد وطرق المناولة ، والمنشآت ، وما إلى ذلك.

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

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

ما هو التفكير ، ولماذا هو مفيد؟

أنا مهتم بشكل خاص بجافا ، لكنني أفترض أن المبادئ هي نفسها في أي لغة.


أريد فقط إضافة بعض النقاط إلى كل ما تم إدراجه.

باستخدام Reflection API ، يمكنك كتابة أسلوب toString() عالمي لأي كائن.

من المفيد في التصحيح.

في ما يلي بعض الأمثلة:

class ObjectAnalyzer {

   private ArrayList<Object> visited = new ArrayList<Object>();

   /**
    * Converts an object to a string representation that lists all fields.
    * @param obj an object
    * @return a string with the object's class name and all field names and
    * values
    */
   public String toString(Object obj) {
      if (obj == null) return "null";
      if (visited.contains(obj)) return "...";
      visited.add(obj);
      Class cl = obj.getClass();
      if (cl == String.class) return (String) obj;
      if (cl.isArray()) {
         String r = cl.getComponentType() + "[]{";
         for (int i = 0; i < Array.getLength(obj); i++) {
            if (i > 0) r += ",";
            Object val = Array.get(obj, i);
            if (cl.getComponentType().isPrimitive()) r += val;
            else r += toString(val);
         }
         return r + "}";
      }

      String r = cl.getName();
      // inspect the fields of this class and all superclasses
      do {
         r += "[";
         Field[] fields = cl.getDeclaredFields();
         AccessibleObject.setAccessible(fields, true);
         // get the names and values of all fields
         for (Field f : fields) {
            if (!Modifier.isStatic(f.getModifiers())) {
               if (!r.endsWith("[")) r += ",";
               r += f.getName() + "=";
               try {
                  Class t = f.getType();
                  Object val = f.get(obj);
                  if (t.isPrimitive()) r += val;
                  else r += toString(val);
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
         }
         r += "]";
         cl = cl.getSuperclass();
      } while (cl != null);

      return r;
   }    
}

الانعكاس هو مجموعة من الوظائف التي تسمح لك بالوصول إلى معلومات وقت التشغيل الخاصة ببرنامجك وتعديل سلوكه (مع بعض القيود).

من المفيد أنه يسمح لك بتغيير وقت التشغيل بناءً على معلومات التعريف بالبرنامج ، أي يمكنك التحقق من نوع وظيفة الإرجاع وتغيير طريقة التعامل مع الموقف.

في C # على سبيل المثال ، يمكنك تحميل تجميع (a .dll) في وقت التشغيل وفحصه ، والتنقل خلال الفئات واتخاذ الإجراءات وفقًا لما وجدته. كما يتيح لك إنشاء مثيل لفئة ما في وقت التشغيل ، أو استدعاء أسلوبها ، وما إلى ذلك.

أين يمكن أن يكون مفيدا؟ غير مفيد في كل مرة ولكن في حالات محددة. على سبيل المثال ، يمكنك استخدامه للحصول على اسم الفئة لأغراض loggin ، لإنشاء معالجات ديناميكية للأحداث وفقًا لما تم تحديده في ملف التكوين وما إلى ذلك ...


التأمل هو آلية رئيسية للسماح للتطبيق أو إطار العمل بالعمل برمز قد لا يكون قد تم كتابته حتى الآن!

خذ على سبيل المثال ملف web.xml النموذجي. سيحتوي هذا على قائمة بعناصر servlet التي تحتوي على عناصر فئة servlet متداخلة. ستقوم حاوية servlet بمعالجة ملف web.xml ، وإنشاء مثيل جديد لكل فئة servlet من خلال الانعكاس.

مثال آخر هو Java API لـ XML (JAXP) . حيث يتم توصيل موفر محلل XML بخصائص النظام المعروفة ، والتي يتم استخدامها لإنشاء نسخ جديدة من خلال الانعكاس.

وأخيرًا ، المثال الأكثر شمولية هو Spring الذي يستخدم الانعكاس لإنشاء الفاصوليا ، واستخدامه المكثف للوكلاء


كما يقترح الاسم نفسه فإنه يعكس ما يحمله على سبيل المثال طريقة الفصل ، وما إلى جانب توفير ميزة لاستدعاء طريقة إنشاء مثيل بشكل حيوي في وقت التشغيل.

يتم استخدامه من قبل العديد من الأطر والتطبيقات تحت الخشب لاستدعاء الخدمات دون معرفة الرمز.


لا تدعم كل لغة التفكير ، لكن المبادئ عادة ما تكون هي نفسها في اللغات التي تدعمها.

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

انها مفيدة في الكثير من الحالات. في كل مكان تريد أن تكون قادرًا على توصيل الفصول الدراسية ديناميكيًا في شفرتك. يستخدم المصمموون المتصلون بالعنصر في الكائن الكثير من الانعكاسات ليتمكنوا من إنشاء كائنات من قواعد البيانات دون معرفة مسبقة للأشياء التي سيستخدمونها. أبنية المكونات هي مكان آخر يكون فيه التأمل مفيدًا. أن تكون قادراً على تحميل التعليمات البرمجية بشكل ديناميكي وتحديد ما إذا كانت هناك أنواع هناك والتي تقوم بتطبيق الواجهة الصحيحة لاستخدامها كمكوِّن إضافي أمر مهم في تلك المواقف.


مثال:
خذ على سبيل المثال تطبيقًا بعيدًا يمنح التطبيق الخاص بك كائنًا تحصل عليه باستخدام أساليب API الخاصة به. الآن على أساس الكائن قد تحتاج إلى إجراء نوع من الحوسبة.
يضمن الموفر أن الكائن يمكن أن يكون من 3 أنواع ونحن بحاجة إلى إجراء الحساب على أساس نوع الكائن.
لذلك قد ننفذ في 3 فئات يحتوي كل منها على منطق مختلف. من الواضح أن معلومات الكائن متوفرة في وقت التشغيل بحيث لا يمكنك بشكل ثابت أن تقوم بإجراء عملية حسابية ، لذلك يتم استخدام الانعكاس لتهيئة كائن الطبقة التي تحتاجها لإجراء الحساب على أساس الكائن المستلم من الموفر.


من page وثائق جافا

توفر الحزمة java.lang.reflect فئات وواجهات للحصول على معلومات انعكاسية حول الفئات والكائنات. يسمح التأمل بالوصول البرمجي إلى المعلومات حول الحقول والأساليب والمُنشئين للفئات المحملة ، واستخدام الحقول والأساليب والمصنعين المنعكسين للعمل على نظرائهم الأساسيين ، ضمن القيود الأمنية.

يسمح تطبيق AccessibleObject بقمع عمليات التحقق من الوصول في حالة توفر ReflectPermission اللازم.

الطبقات في هذه الحزمة ، جنبا إلى جنب مع java.lang.Class تستوعب التطبيقات مثل debuggers ، والمترجمين ، مفتشي الجسم ، ومتصفحات الطبقة ، والخدمات مثل Object Serialization و JavaBeans التي تحتاج إلى الوصول إلى إما أعضاء الجمهور من كائن هدف (على أساس فئة وقت التشغيل) أو الأعضاء المعلنة من قبل فئة معينة

ويشمل الوظائف التالية.

  1. الحصول على كائنات فئة ،
  2. دراسة خصائص فئة (حقول ، طرق ، منشئات) ،
  3. إعداد والحصول على قيم الحقول ،
  4. استدعاء أساليب ،
  5. خلق حالات جديدة من الكائنات.

ألقِ نظرة على رابط documentation هذا للأساليب التي يتم كشفها بواسطة Class .

من هذا article (بقلم دنيس سوسنوسكي ، الرئيس ، Sosnoski Software Solutions، Inc) وهذه article (استكشاف الأمن pdf):

أستطيع أن أرى عيوبًا كبيرة من استخدامات Reflection

مستخدم للتفكير:

  1. يوفر طريقة متعددة للغاية لربط مكونات البرنامج ديناميكيًا
  2. من المفيد إنشاء مكتبات تعمل مع الكائنات بطرق عامة جدًا

عيوب انعكاس:

  1. يكون الانعكاس أبطأ بكثير من الرمز المباشر عند استخدامه للوصول إلى المجال والطريقة.
  2. يمكن أن يحجب ما يحدث بالفعل داخل شفرتك
  3. تتجاوز رمز المصدر يمكن أن تخلق مشاكل الصيانة
  4. رمز الانعكاس هو أيضا أكثر تعقيدا من الشفرة المباشرة المقابلة
  5. يسمح بانتهاك قيود أمان Java الرئيسية مثل حماية الوصول إلى البيانات وسلامة الكتابة

انتهاكات عامة:

  1. تحميل الطبقات المقيدة ،
  2. الحصول على مراجع للمبنيين أو الأساليب أو المجالات لفئة محددة ،
  3. إنشاء مثيلات كائن جديدة أو استدعاء أساليب أو الحصول على أو تعيين قيم حقل فئة مقيد.

ألقِ نظرة على سؤال SE هذا بخصوص إساءة استخدام ميزة الانعكاس:

كيف يمكنني قراءة حقل خاص في Java؟

ملخص:

يمكن أن يؤدي الاستخدام غير الآمن لوظائفها التي يتم إجراؤها من خلال رمز النظام بسهولة إلى التنازل عن وضع أمان Java l. لذلك استخدم هذه الميزة لماما


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

افترض أن لديك طريقة add(Int a,int b) . يفترض رمز بايت المكافئ B1 . إذا افترض أن لديك 1000 طريقة تمت add في نظامك. الآن تريد التحقق من قيمة المعلمة a و b قبل استدعاء الأسلوب. لذلك ، يمكنك لصق التعليمات البرمجية الخاصة بك إلى برنامج آخر أو إطار عمل يستخدم انعكاس لفحص قيمة رمز بايت بشكل حيوي باستخدام Object.getClass.getMethod() . هناك عدة فئات للفحص. يمكن أن تضيف المزيد من العملية قبل استدعاء طريقة add . ولكن ، لا يعرف البرنامج نفسه أو برنامج أو إطار عمل آخر عن الكائن الذي يحتوي على طريقة باسم add . في الغالب في حقن التبعية ، يستخدم في الغالب استخدام البرمجة الموجهة الجانب من الانعكاس.


يستخدم انعكاس الاسم لوصف الكود القادر على فحص الكود الآخر في نفس النظام (أو نفسه).

على سبيل المثال ، لنفترض أن لديك كائنًا من نوع غير معروف في Java ، وترغب في استدعاء طريقة "doSomething" عليه إذا كان موجودًا. لم يتم تصميم نظام الكتابة الثابت في جافا لدعم هذا إلا إذا كان الكائن يتطابق مع واجهة معروفة ، ولكن باستخدام الانعكاس ، يمكن أن تبحث الكود الخاص بك في الكائن ومعرفة ما إذا كان يحتوي على طريقة تسمى 'doSomething' ثم قم باستدعاءها إذا كنت اريد ان.

لذا ، لإعطائك مثالاً رمزًا لهذا في Java (تخيل أن الكائن المعني هو foo):

Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);

إحدى حالات الاستخدام الشائعة جدًا في جافا هي الاستخدام مع التعليقات التوضيحية. على سبيل المثال ، سوف تستخدم JUnit 4 انعكاسًا للبحث في الفصول الدراسية الخاصة بك للطرق الموسومة بعلامةTest التوضيحية ، ثم ستقوم بالاتصال بها عند تشغيل اختبار الوحدة.

هناك بعض الأمثلة على التفكير الجيد للبدء في http://docs.oracle.com/javase/tutorial/reflect/index.html

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

تحديث مهم من تعليق:

إن القدرة على فحص التعليمة البرمجية في النظام ورؤية أنواع الكائنات ليست انعكاسًا ، بل بالأحرى نوع Introspection. الانعكاس هو القدرة على إجراء تعديلات في وقت التشغيل من خلال الاستفادة من الاستبطان. التمييز ضروري هنا لأن بعض اللغات تدعم الاستبطان ، ولكنها لا تدعم التفكير. أحد الأمثلة على ذلك هو C ++


يعتبر Java Reflection قويًا جدًا ويمكن أن يكون مفيدًا للغاية. يجعل Java Reflection من الممكن فحص الطبقات والواجهات والحقول والطرق في وقت التشغيل ، دون معرفة أسماء الفئات والطرق وغير ذلك في وقت الترجمة. من الممكن أيضًا إنشاء كائنات جديدة ، واستحضار أساليب والحصول على قيم الحقل / تعيينها باستخدام الانعكاس.

مثال Java Reflection سريع ليوضح لك كيف يبدو شكل التفكير:

Method[] methods = MyObject.class.getMethods();

    for(Method method : methods){
        System.out.println("method = " + method.getName());
    }

يحصل هذا المثال على كائن Class من الفئة تسمى MyObject. باستخدام كائن الفئة ، يحصل المثال على قائمة بالطرق في تلك الفئة ، ويقوم بتكرار الطرق وطباعة أسمائها.

بالضبط كيف يتم شرح كل هذه الأعمال هنا

تعديل : بعد ما يقرب من عام واحد ، أقوم بتحرير هذه الإجابة ، بينما قرأت عن التأمل حصلت على عدد قليل من استخدامات التأمل.

  • يستخدم الربيع تكوين الفول مثل:


<bean id="someID" class="com.example.Foo">
    <property name="someField" value="someValue" />
</bean>

عندما يعالج سياق Spring هذا العنصر <bean> ، فسيستخدم Class.forName (String) مع الوسيطة "com.example.Foo" لتكوين تلك الفئة.

وسيستخدم مرة أخرى الانعكاس للحصول على المحدد المناسب لعنصر <property> وتعيين قيمته إلى القيمة المحددة.

  • يستخدم Junit Reflection بشكل خاص لاختبار أساليب Private / Protected.

للأساليب الخاصة ،

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

للحقول الخاصة ،

Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);

يمنحك الانعكاس القدرة على كتابة رمز عام أكثر. يسمح لك بإنشاء كائن في وقت التشغيل واستدعاء أسلوبه في وقت التشغيل. وبالتالي يمكن جعل البرنامج معلمات higly. كما أنها تسمح بتأمل الكائن والطبقة لكشف متغيراته وطريقة تعرضه للعالم الخارجي.


استخدامات التفكير

يتم استخدام الانعكاس عادةً بواسطة البرامج التي تتطلب القدرة على فحص أو تعديل سلوك وقت التشغيل للتطبيقات التي تعمل في الجهاز الظاهري لـ Java. هذه ميزة متقدمة نسبياً ويجب استخدامها فقط من قبل المطورين الذين لديهم فهم قوي لأساسيات اللغة. مع وضع هذا التحذير في الاعتبار ، يعتبر التفكير أسلوبًا قويًا ويمكن أن يمكّن التطبيقات من إجراء عمليات قد تكون مستحيلة.

ميزات القابلية للتوسعة

قد يقوم أحد التطبيقات باستخدام الفئات الخارجية التي يحددها المستخدم عن طريق إنشاء مثيلات كائنات قابلة للتوسعة باستخدام أسماءها المؤهلة بالكامل. المستعرضات فئة وبيئات التطوير المرئي يجب أن يكون مستعرض فئة لتتمكن من تعداد أعضاء الفئات. يمكن أن تستفيد بيئات التطوير المرئي من الاستفادة من معلومات الكتابة المتاحة في التفكير لمساعدة المطور في كتابة التعليمات البرمجية الصحيحة. مصحح الأخطاء وأدوات الاختبار يحتاج مصححو البرامج إلى فحص الأعضاء الخاصين في الفصول الدراسية. يمكن أن تستخدم أدوات الاختبار عملية التفكير في استدعاء مجموعة من واجهات برمجة التطبيقات المحددة القابلة للاكتشاف على فئة معينة بشكل منهجي ، وذلك لضمان مستوى مرتفع من تغطية الشفرة في مجموعة اختبار.

عيوب انعكاس

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

  • النفقات العامة

لأن الانعكاس ينطوي على أنواع يتم حلها ديناميكيًا ، لا يمكن إجراء بعض تحسينات الأجهزة الظاهرية في Java. وبالتالي ، يكون للعمليات العاكسة أداء أبطأ من نظيراتها غير العاكسة ، ويجب تجنبها في أقسام الكود التي تسمى في كثير من الأحيان في التطبيقات الحساسة للأداء.

  • القيود الأمنية

يتطلب الانعكاس الحصول على إذن وقت التشغيل والذي قد لا يكون موجودًا عند التشغيل تحت إدارة الأمان. هذا في اعتبار هامة لرمز يجب تشغيله في سياق أمان مقيد ، مثل في برنامج صغير.

  • التعرض للداخل

بما أن الانعكاس يسمح للشفرة بتنفيذ عمليات قد تكون غير قانونية في الشفرة غير العاكسة ، مثل الوصول إلى الحقول والأساليب الخاصة ، فإن استخدام الانعكاس يمكن أن يؤدي إلى آثار جانبية غير متوقعة ، مما قد يجعل الكود غير فعال ويمكن أن يدمر قابلية النقل. الكود الانعكاس يكسر التجريدات ، وبالتالي قد يغير السلوك مع ترقيات النظام الأساسي.

المصدر: واجهة برمجة تطبيقات الانعكاس


الانعكاس هو واجهة برمجة التطبيقات (API) التي يتم استخدامها لفحص أو تعديل سلوك الطرق والفئات والواجهات في وقت التشغيل.

  1. يتم توفير الفئات المطلوبة للتفكير ضمن java.lang.reflect package .
  2. يقدم لنا التأمل معلومات حول الفئة التي ينتمي إليها الكائن وأيضًا طرق ذلك الصف التي يمكن تنفيذها باستخدام الكائن.
  3. من خلال الانعكاس يمكننا استدعاء أساليب في وقت التشغيل بغض النظر عن محدد الوصول المستخدم معهم.

توفر حزم java.lang.reflect و java.lang.reflect فئات للانعكاس java.

يمكن استخدام التفكير للحصول على معلومات حول -

  1. الفئة يتم استخدام الأسلوب getClass() للحصول على اسم الفئة التي ينتمي إليها الكائن.

  2. Constructors يتم استخدام أسلوب getConstructors() للحصول على منشئات عامة للفئة التي ينتمي إليها كائن.

  3. الطرق يتم استخدام الطريقة getMethods() للحصول على الأساليب العامة للفئة التي تنتمي إليها الكائنات.

يتم استخدام واجهة برمجة تطبيقات الانعكاس بشكل أساسي في:

IDE (بيئة التطوير المتكاملة) على سبيل المثال Eclipse و MyEclipse و NetBeans إلخ.
المصحح وأدوات الاختبار الخ

مزايا استخدام انعكاس:

ميزات القابلية للتوسعة : قد يستفيد التطبيق من الطبقات الخارجية التي يحددها المستخدم عن طريق إنشاء مثيلات كائنات قابلة للتوسعة باستخدام أسماءها المؤهلة بالكامل.

أدوات التصحيح والاختبار: يستخدم مصحح الأخطاء خاصية الانعكاس لفحص الأعضاء في الطبقات.

السلبيات:

النفقات العلوية الأداء: تتميز العمليات العاكسة بأداء أبطأ من نظيراتها غير العاكسة ، ويجب تجنبها في أقسام الكود التي يطلق عليها كثيرًا في التطبيقات الحساسة للأداء.

التعرض للداخل: الكود الانعكاس يكسر التجريدات وبالتالي قد يتغير السلوك مع ترقيات المنصة.

المرجع: Java Reflection javarevisited.blogspot.in





terminology