Comment une méthode
public native int getModifiers()
d'une classe Class
et certaines constantes d'une classe sont liées Modifier
. Disons 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 Class
pour 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 specificModifier
sera égal à l'une des constantes de classe Modifier
: Modifier.PUBLIC
, Modifier.STATIC
etc. (nous considérerons les constantes restantes ci-dessous). Et la méthode nous reviendra true
si 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 0001Modifier.PRIVATE
= 2 = 0000 0010Modifier.PROTECTED
= 4 = 0000 0100Modifier.STATIC
= 8 = 0000 1000Modifier.FINAL
= 16 = 0001 0000Modifier.SYNCHRONIZED
= 32 = 0010 0000Modifier.VOLATILE
= 64 = 0100 0000Modifier.TRANSIENT
= 128 = 1 000 0000Modifier.NATIVE
= 256 = 1 0000 0000Modifier.INTERFACE
= 512 = 10 0000 0000Modifier.ABSTRACT
= 1024 = 100 0000 0000NestedClass.class.getModifiers()
= 1033 = 100 0000 1001
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 NestedClass
les modificateurs d'accès suivants : public
static
abstract
. Un PUBLIC
est é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 ( NestedClass
not 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 ;
return
reviendra 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.
return
reviendra true
, car 1024 > 0 - true
. Il existe donc un tel modificateur d'accès. De 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;
}
}
GO TO FULL VERSION