JavaRush /Java Blog /Random-IT /API di riflessione. Come funziona il metodo getModifiers(...
Георгий
Livello 22
Санкт-Петербург

API di riflessione. Come funziona il metodo getModifiers() nella classe Class

Pubblicato nel gruppo Random-IT
Come sono correlati un metodo public native int getModifiers()di una classe Classe alcune costanti di una classe Modifier. API di riflessione.  Come funziona il metodo getModifiers() nella Classe - 1Diciamo che abbiamo una classe:
public static abstract class NestedClass{
}
Il metodo getModifiers()restituisce il risultato come un numero in cui sono crittografati i modificatori di accesso della classe o del metodo da cui viene chiamato. Per richiamare getModifiers()una classe, ad esempio per NestedClass, è necessario creare un oggetto classe Classper la classe NestedClass. E Class<NestedClass>chiama getModifiers().
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
Oppure in una riga e visualizza il risultato e la sua rappresentazione binaria:
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers));
Sullo schermo:

classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001
Ok, ma perché questo numero in particolare? Diamo un'occhiata all'esempio della classe NestedClass. Diciamo che abbiamo un metodo:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
I suoi parametri includeranno: int allModifiers = NestedClass.class.getModifiers(), come nell'esempio sopra. A int specificModifiersarà uguale a una delle costanti della classe Modifier: Modifier.PUBLIC, Modifier.STATICecc. (considereremo le rimanenti costanti di seguito). E il metodo ci tornerà truese la classe contiene il modificatore di accesso passato a specificModifier. Altrimenti - false. Il codice nella classe di test sarà simile al seguente:
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
Come implementare la logica del metodo isModifierSet? Rappresentiamo i modificatori nella classe nel sistema binario Modifier: (ad esempio, Modifier.FINAL= 0x00000010, o nel 10° sistema - 16. 16 in binario = 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
E cosa vediamo? Per ogni modificatore, viene preso un numero nel 10° in modo che nel 2° il loro 1 si sposti di una posizione a sinistra. Ed getModifiers()è calcolato in modo tale che se una classe contiene un determinato modificatore di accesso, lo stesso bit del modificatore di accesso diventa uguale a 1. Nei NestedClassseguenti modificatori di accesso: public static abstract. Uno PUBLICè uguale a 0 cifra (più a destra). B STATIC- 3. B ABSTRACT- 10. E ora guardiamo il nostro NestedClass.class.getModifiers(): nelle cifre 0, 3 e 10 ne ha uno! E tutto il resto è zero. Successivamente passiamo alla risoluzione del problema. Dobbiamo capire se il nostro getModifiers()modificatore specifico contiene. Consideriamo il caso del modificatore final. Modifier.FINAL= 16 = 0001 0000, quindi uno è uguale alla 4a cifra. Per analogia con l’esempio sopra, vediamo se our NestedClass.class.getModifiers()= 100 0000 1001 Modifier.FINAL. Qui la quarta cifra è uguale a 0. Ciò significa che non contiene, il che è vero ( NestedClassnot final). Ma quale logica devo scrivere nel metodo? Dobbiamo applicare un valore logico AND (&), che è 1 se entrambi i bit sono 1. Altrimenti, 0. Alla fine il nostro metodo sarà simile a questo:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
        return (allModifiers & specificModifier) > 0;
    }
Assicuriamoci che il codice funzioni e mostriamo perché funziona. Calcoliamo NestedClass.class.getModifiers() & Modifier.FINAL:
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 000 0001 0000 - Modifier.FINAL(aggiunti 3 zeri a sinistra per comodità)
  • 000 0000 0000 - risposta 0. Non abbiamo una sola unità, perché solo 1 e 1 = 1. 1 e 0 = 0, 0 e 1 = 0, 0 e 0 = 0;
Ciò significa che la nostra espressione in returnritornerà false, perché 0 > 0 - false. Ciò significa che non esiste tale modificatore di accesso. Guardiamo Modifier.ABSTRACT & NestedClass.class.getModifiers():
  • 100 0000 0000 -Modifier.ABSTRACT
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 100 0000 0000 - Le unità più a sinistra corrispondevano. Converti in 10: la risposta è 1024.
Ciò significa che la nostra espressione in returnritornerà true, perché 1024 > 0 - true. Quindi esiste un tale modificatore di accesso. API di riflessione.  Come funziona il metodo getModifiers() nella Classe - 2Allo stesso modo, questo metodo può essere applicato sia ai metodi della classe che ai campi della classe. Il codice per il campo sarà simile al seguente:
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;
    }
}
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION