JavaRush /Blog Java /Random-FR /API de réflexion. Comment fonctionne la méthode getModifi...
Георгий
Niveau 22
Санкт-Петербург

API de réflexion. Comment fonctionne la méthode getModifiers() dans la classe Class

Publié dans le groupe Random-FR
Comment une méthode public native int getModifiers()d'une classe Classet certaines constantes d'une classe sont liées Modifier. API de réflexion.  Comment fonctionne la méthode getModifiers() en Classe - 1Disons que nous avons une classe :
public static abstract class NestedClass{
}
La méthode getModifiers()renvoie le résultat sous la forme d'un nombre dans lequel sont chiffrés les modificateurs d'accès de la classe ou de la méthode à partir de laquelle elle est appelée. Pour faire appel à getModifiers()une classe, par exemple pour NestedClass, vous devez créer un objet classe Classpour la classe NestedClass. Et Class<NestedClass>appelle getModifiers().
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
Ou sur une seule ligne et afficher le résultat et sa représentation binaire :
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers));
Sur l'écran:

classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001
D'accord, mais pourquoi ce numéro en particulier ? Regardons l'exemple de la classe NestedClass. Disons que nous avons une méthode :
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
Ses paramètres incluront : int allModifiers = NestedClass.class.getModifiers(), comme dans l'exemple ci-dessus. A int specificModifiersera égal à l'une des constantes de classe Modifier: Modifier.PUBLIC, Modifier.STATICetc. (nous considérerons les constantes restantes ci-dessous). Et la méthode nous reviendra truesi la classe contient le modificateur d'accès passé à specificModifier. Sinon - false. Le code de la classe de test ressemblera à ceci :
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
Comment mettre en œuvre la logique de la méthode isModifierSet? Représentons les modificateurs de la classe dans le système binaire Modifier: (par exemple, Modifier.FINAL= 0x00000010, ou dans le 10ème système - 16, 16 en binaire = 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 = 1 000 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
Et que voit-on ? Pour chaque modificateur, un nombre dans le 10ème est pris tel que dans le 2ème, leur 1 se déplace d'une place vers la gauche. Et getModifiers()il est calculé de telle manière que si une classe contient un certain modificateur d'accès, alors le même bit que dans le modificateur d'accès devient égal à 1. Dans NestedClassles modificateurs d'accès suivants : public static abstract. Un PUBLICest égal à 0 chiffre (le plus à droite). B STATIC- 3. B ABSTRACT- 10. Et maintenant regardons le nôtre NestedClass.class.getModifiers(): Dans les chiffres 0, 3 et 10 il en a un ! Et tout le reste est nul. Ensuite, nous passons à la résolution du problème. Nous devons comprendre si notre getModifiers()modificateur spécifique contient. Considérons le cas du modificateur final. Modifier.FINAL= 16 = 0001 0000, donc un est égal au 4ème chiffre. Par analogie avec l'exemple ci-dessus, voyons si le nôtre NestedClass.class.getModifiers()= 100 0000 1001 Modifier.FINAL. Ici le 4ème chiffre est égal à 0. Cela signifie qu'il ne contient pas, ce qui est vrai ( NestedClassnot final). Mais quelle logique dois-je écrire dans la méthode ? Nous devons appliquer une valeur logique AND (&), qui est 1 si les deux bits sont 1. Sinon, 0. Notre méthode ressemblera finalement à ceci :
public static boolean isModifierSet(int allModifiers, int specificModifier) {
        return (allModifiers & specificModifier) > 0;
    }
Assurons-nous que le code fonctionne et montrons pourquoi il fonctionne. On calcule NestedClass.class.getModifiers() & Modifier.FINAL:
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 000 0001 0000 - Modifier.FINAL(ajout de 3 zéros à gauche pour plus de commodité)
  • 000 0000 0000 - réponse 0. Nous n'avons pas une seule unité, car seulement 1 & 1 = 1. 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0 ;
Cela signifie que notre expression in returnreviendra false, car 0 > 0 - false. Cela signifie qu'il n'existe pas de tel modificateur d'accès. Regardons Modifier.ABSTRACT & NestedClass.class.getModifiers():
  • 100 0000 0000 -Modifier.ABSTRACT
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 100 0000 0000 - Les unités les plus à gauche correspondent. Convertissez en 10ème : la réponse est 1024.
Cela signifie que notre expression in returnreviendra true, car 1024 > 0 - true. Il existe donc un tel modificateur d'accès. API de réflexion.  Comment fonctionne la méthode getModifiers() en Classe - 2De la même manière, cette méthode peut être appliquée à la fois aux méthodes de classe et aux champs de classe. Le code du champ ressemblera à ceci :
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;
    }
}
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION