JavaRush /Java-Blog /Random-DE /Reflection-API. So funktioniert die Methode getModifiers(...
Георгий
Level 22
Санкт-Петербург

Reflection-API. So funktioniert die Methode getModifiers() in der Class-Klasse

Veröffentlicht in der Gruppe Random-DE
Wie eine Methode public native int getModifiers()einer Klasse Classund einige Konstanten einer Klasse zusammenhängen Modifier. Reflection-API.  So funktioniert die Methode getModifiers() in Klasse 1Nehmen wir an, wir haben eine Klasse:
public static abstract class NestedClass{
}
Die Methode getModifiers()gibt das Ergebnis als Zahl zurück, in der die Zugriffsmodifikatoren der Klasse oder Methode, von der sie aufgerufen wird, verschlüsselt sind. Um eine Klasse aufzurufen getModifiers(), beispielsweise für NestedClass, müssen Sie ein Klassenobjekt Classfür die Klasse erstellen NestedClass. Und Class<NestedClass>Ruf an getModifiers().
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
Oder in einer Zeile und zeigen Sie das Ergebnis und seine binäre Darstellung an:
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers));
Auf dem Bildschirm:

classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001
Okay, aber warum gerade diese Zahl? Schauen wir uns das Beispiel der Klasse an NestedClass. Nehmen wir an, wir haben eine Methode:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
Zu seinen Parametern gehören: int allModifiers = NestedClass.class.getModifiers(), wie im obigen Beispiel. A int specificModifierentspricht einer der Klassenkonstanten Modifier: Modifier.PUBLICusw. Modifier.STATIC(Die übrigen Konstanten betrachten wir weiter unten). Und die Methode kehrt zu uns zurück true, wenn die Klasse den an übergebenen Zugriffsmodifikator enthält specificModifier. Wenn nicht - false. Der Code in der Testklasse sieht folgendermaßen aus:
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
Wie implementiert man die Logik der Methode isModifierSet? Stellen wir Modifikatoren in der Klasse im Binärsystem dar Modifier: (zum Beispiel Modifier.FINAL= 0x00000010 oder im 10. System - 16. 16 im Binärsystem = 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
Und was sehen wir? Für jeden Modifikator wird eine Zahl in der 10. genommen, so dass sich ihre 1 in der 2. um eine Stelle nach links verschiebt. Und getModifiers()es wird so berechnet, dass, wenn eine Klasse einen bestimmten Zugriffsmodifikator enthält, dasselbe Bit wie im Zugriffsmodifikator gleich 1 wird. In NestedClassden folgenden Zugriffsmodifikatoren: public static abstract. Eins PUBLICentspricht der Ziffer 0 (am weitesten rechts). B STATIC- 3. B ABSTRACT- 10. Und jetzt schauen wir uns unsere an NestedClass.class.getModifiers(): In den Ziffern 0, 3 und 10 steht eins! Und alle anderen sind Null. Als nächstes gehen wir zur Lösung des Problems über. Wir müssen verstehen, ob unser getModifiers()spezifischer Modifikator enthält. Betrachten wir den Fall für den Modifikator final. Modifier.FINAL= 16 = 0001 0000, also ist eins gleich der 4. Ziffer. Schauen wir uns analog zum obigen Beispiel an, ob unsere NestedClass.class.getModifiers()= 100 0000 1001 ist Modifier.FINAL. Hier ist die 4. Ziffer gleich 0. Dies bedeutet, dass sie nicht enthält, was wahr ist ( NestedClassnicht final). Aber welche Logik soll ich in die Methode schreiben? Wir müssen einen logischen Wert anwenden AND (&), der 1 ist, wenn beide Bits 1 sind. Andernfalls 0. Unsere Methode wird schließlich so aussehen:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
        return (allModifiers & specificModifier) > 0;
    }
Stellen wir sicher, dass der Code funktioniert, und zeigen wir, warum er funktioniert. Wir berechnen NestedClass.class.getModifiers() & Modifier.FINAL:
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 000 0001 0000 – Modifier.FINAL(der Einfachheit halber wurden links drei Nullen hinzugefügt)
  • 000 0000 0000 - Antwort 0. Wir haben keine einzige Einheit, weil nur 1 & 1 = 1. 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0;
Das bedeutet, dass unser Ausdruck in returnwill return false, weil 0 > 0 - false. Dies bedeutet, dass es keinen solchen Zugriffsmodifikator gibt. Lass uns nachsehen Modifier.ABSTRACT & NestedClass.class.getModifiers():
  • 100 0000 0000 -Modifier.ABSTRACT
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 100 0000 0000 – Die Einheiten ganz links, die übereinstimmen. In 10. umrechnen: Die Antwort ist 1024.
Das bedeutet, dass unser Ausdruck in returnwill return true, weil 1024 > 0 - true. Es gibt also einen solchen Zugriffsmodifikator. Reflection-API.  So funktioniert die Methode getModifiers() in Klasse 2Auf die gleiche Weise kann diese Methode sowohl auf Klassenmethoden als auch auf Klassenfelder angewendet werden. Der Code für das Feld sieht folgendermaßen aus:
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;
    }
}
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION