JavaRush /وبلاگ جاوا /Random-FA /Reflection API. نحوه عملکرد متد getModifiers() در کلاس Cl...
Георгий
مرحله
Санкт-Петербург

Reflection API. نحوه عملکرد متد getModifiers() در کلاس Class

در گروه منتشر شد
چگونه یک متد public native int getModifiers()از یک کلاس Classو چند ثابت از یک کلاس به هم مرتبط هستند Modifier. Reflection API.  نحوه عملکرد متد 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 = 0000 0001
  • Modifier.PRIVATE= 2 = 0000 0010
  • Modifier.PROTECTED= 4 = 0000 0100
  • Modifier.STATIC= 8 = 0000 1000
  • Modifier.FINAL= 16 = 0001 0000
  • Modifier.SYNCHRONIZED= 32 = 0010 0000
  • Modifier.VOLATILE= 64 = 0100 0000
  • Modifier.TRANSIENT= 128 = 1000 0000
  • Modifier.NATIVE= 256 = 1 0000 0000
  • Modifier.INTERFACE= 512 = 10 0000 0000
  • Modifier.ABSTRACT = 1024 = 100 0000 0000
  • NestedClass.class.getModifiers()= 1033 = 100 0000 1001
و ما چه می بینیم؟ برای هر اصلاح کننده، عددی در عدد 10 در نظر گرفته می شود که در 2، 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، بنابراین یک برابر است با رقم 4. با قیاس با مثال بالا، بیایید ببینیم که آیا ما NestedClass.class.getModifiers()= 100 0000 1001 Modifier.FINAL. در اینجا رقم 4 برابر است با 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.
این به این معنی است که عبارت ما در returnبازگشت خواهد شد false، زیرا 0 > 0 - false. این بدان معناست که چنین اصلاح کننده دسترسی وجود ندارد. بیایید نگاه بیندازیم Modifier.ABSTRACT & NestedClass.class.getModifiers():
  • 100 0000 0000 -Modifier.ABSTRACT
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 100 0000 0000 - سمت چپ ترین واحدها مطابقت دارند. تبدیل به 10: پاسخ 1024 است.
این به این معنی است که عبارت ما در returnبازگشت خواهد شد true، زیرا 1024 > 0 - true. بنابراین چنین اصلاح کننده دسترسی وجود دارد. Reflection API.  نحوه عملکرد متد 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