JavaRush /בלוג Java /Random-HE /Reflection API. כיצד פועלת המתודה getModifiers() במחלקה C...
Георгий
רָמָה
Санкт-Петербург

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,000
  • 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 ספרה (הכי רחוק מימין). B STATIC- 3. B 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;
זה אומר שהביטוי שלנו ב 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