JavaRush /مدونة جافا /Random-AR /واجهة برمجة تطبيقات الانعكاس. كيف تعمل طريقة getModifiers...
Георгий
مستوى
Санкт-Петербург

واجهة برمجة تطبيقات الانعكاس. كيف تعمل طريقة getModifiers() في فئة Class

نشرت في المجموعة
كيف ترتبط طريقة public native int getModifiers()من الفصل Classوبعض الثوابت من الفصل Modifier. واجهة برمجة تطبيقات الانعكاس.  كيف تعمل طريقة getModifiers() في الفئة - 1لنفترض أن لدينا فئة:
public static abstract class NestedClass{
}
تقوم الطريقة getModifiers()بإرجاع النتيجة كرقم يتم فيه تشفير معدلات الوصول للفئة أو الطريقة التي يتم استدعاؤها منها. لاستدعاء getModifiers()فئة، على سبيل المثال NestedClass، تحتاج إلى إنشاء كائن فئة Classللفئة NestedClass. و Class<NestedClass>اتصل getModifiers().
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
أو في سطر واحد وعرض النتيجة وتمثيلها الثنائي:
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers));
على الشاشة:

classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001
حسنًا، ولكن لماذا هذا الرقم بالذات؟ دعونا نلقي نظرة على مثال الفصل NestedClass. لنفترض أن لدينا طريقة:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
ستتضمن معلماته: int allModifiers = NestedClass.class.getModifiers()، كما في المثال أعلاه. ستكون A int specificModifierمساوية لأحد ثوابت الفئة Modifier: Modifier.PUBLIC، Modifier.STATICإلخ. (سننظر في الثوابت المتبقية أدناه). وستعود الطريقة إلينا trueإذا كان الفصل يحتوي على معدّل الوصول الذي تم تمريره إليه specificModifier. ان لم - false. سيبدو الرمز الموجود في فئة الاختبار كما يلي:
boolean isPublic = isModifierSet(classModifiers, Modifier.PUBLIC);
boolean isInterface = isModifierSet(classModifiers, Modifier.INTERFACE);
boolean isAbstract = isModifierSet(classModifiers, Modifier.ABSTRACT);

System.out.printf("\"Is NestedClass public?\" - %b%n", isPublic); //true
System.out.printf("\"Is NestedClass interface?\" - %b%n", isInterface); //false
System.out.printf("\"Is NestedClass abstract?\" - %b%n", isAbstract); //true
كيفية تنفيذ منطق الأسلوب isModifierSet؟ لنمثل المعدلات في الفصل في النظام الثنائي Modifier: (على سبيل المثال، Modifier.FINAL= 0x00000010، أو في النظام العاشر - 16. 16 في النظام الثنائي = 00010000)
  • Modifier.PUBLIC = 1 = 00000001
  • Modifier.PRIVATE= 2 = 00000010
  • Modifier.PROTECTED= 4 = 00000100
  • Modifier.STATIC= 8 = 00001000
  • Modifier.FINAL= 16 = 00010000
  • Modifier.SYNCHRONIZED= 32 = 00100000
  • Modifier.VOLATILE= 64 = 01000000
  • Modifier.TRANSIENT= 128 = 10000000
  • Modifier.NATIVE= 256 = 100000000
  • Modifier.INTERFACE= 512 = 100000000
  • Modifier.ABSTRACT = 1024 = 10000000000
  • NestedClass.class.getModifiers()= 1033 = 10000001001
وماذا نرى؟ لكل معدل، يتم أخذ رقم في الرقم العاشر بحيث يتحرك الرقم 1 في الرقم الثاني مكانًا واحدًا إلى اليسار. ويتم getModifiers()حسابه بطريقة أنه إذا كانت الفئة تحتوي على معدّل وصول معين، فإن نفس البت الموجود في معدّل الوصول يصبح مساويًا لـ 1. في NestedClassمعدّلات الوصول التالية: public static abstract. واحد PUBLICيساوي 0 رقم (أبعد إلى اليمين). ب STATIC- 3. ب ABSTRACT- 10. والآن ننظر إلى رقمنا NestedClass.class.getModifiers(): في الأرقام 0 و3 و10 يوجد رقم واحد! والباقي كله صفر. بعد ذلك ننتقل إلى حل المشكلة. نحن بحاجة إلى فهم ما إذا كان getModifiers()معدّلنا المحدد يحتوي على. دعونا ننظر في حالة المعدل final. Modifier.FINAL= 16 = 0001 0000، لذا فإن الواحد يساوي الرقم الرابع. قياسًا على المثال أعلاه، دعونا نرى ما إذا كان لدينا NestedClass.class.getModifiers()= 100 0000 1001 Modifier.FINAL. هنا الرقم الرابع يساوي 0. وهذا يعني أنه لا يحتوي على، وهذا صحيح ( NestedClassلا final). لكن ما هو المنطق الذي يجب أن أكتبه في الطريقة؟ نحن بحاجة إلى تطبيق قيمة منطقية AND (&)، وهي 1 إذا كان كلا البتين 1. وإلا، 0. ستبدو طريقتنا في النهاية كما يلي:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
        return (allModifiers & specificModifier) > 0;
    }
دعونا نتأكد من أن الكود يعمل ونوضح سبب عمله. نحن نحسب NestedClass.class.getModifiers() & Modifier.FINAL:
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 000 0001 0000 - Modifier.FINAL(تم إضافة 3 أصفار إلى اليسار للراحة)
  • 000 0000 0000 - الإجابة 0. ليس لدينا وحدة واحدة، لأن فقط 1 & 1 = 1. 1 & 0 = 0، 0 & 1 = 0، 0 & 0 = 0؛
هذا يعني أن تعبيرنا in returnسيعود false، لأن 0 > 0 - false. هذا يعني أنه لا يوجد معدل وصول من هذا القبيل. دعونا ننظر Modifier.ABSTRACT & NestedClass.class.getModifiers():
  • 100 0000 0000 -Modifier.ABSTRACT
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 100 0000 0000 - الوحدات الموجودة في أقصى اليسار متطابقة. التحويل إلى العاشر: الجواب هو 1024.
هذا يعني أن تعبيرنا in returnسيعود true، لأن 1024 > 0 - true. لذلك هناك مثل هذا المعدل الوصول. واجهة برمجة تطبيقات الانعكاس.  كيف تعمل طريقة getModifiers() في الفئة - 2بنفس الطريقة، يمكن تطبيق هذه الطريقة على كل من أساليب الفصل وحقول الفصل. سيبدو رمز الحقل كما يلي:
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class A {
    private static transient volatile String name = "Bob";

    public static void main(String[] args) throws NoSuchFieldException {

        Field field = A.class.getDeclaredField("name");
        int fieldModifiers = field.getModifiers();

        boolean isPublic = isModifierSet(fieldModifiers, Modifier.PUBLIC);
        boolean isFinal = isModifierSet(fieldModifiers, Modifier.FINAL);
        boolean isVolatile = isModifierSet(fieldModifiers, Modifier.VOLATILE);

        System.out.printf("\"Is A.name public?\" - %b%n", isPublic); //false
        System.out.printf("\"Is A.name final?\" - %b%n", isFinal); //false
        System.out.printf("\"Is A.name volatile?\" - %b%n", isVolatile); //true
    }
    public static boolean isModifierSet(int allModifiers, int specificModifier) {
        return (allModifiers & specificModifier) > 0;
    }
}
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION