Come sono correlati un metodo
public native int getModifiers()
di una classe Class
e alcune costanti di una classe Modifier
. Diciamo 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 Class
per 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 specificModifier
sarà uguale a una delle costanti della classe Modifier
: Modifier.PUBLIC
, Modifier.STATIC
ecc. (considereremo le rimanenti costanti di seguito). E il metodo ci tornerà true
se 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 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 = 1000 0000Modifier.NATIVE
= 256 = 1 0000 0000Modifier.INTERFACE
= 512 = 10 0000 0000Modifier.ABSTRACT
= 1024 = 100 0000 0000NestedClass.class.getModifiers()
= 1033 = 100 0000 1001
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 NestedClass
seguenti 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 ( NestedClass
not 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;
return
ritornerà 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.
return
ritornerà true
, perché 1024 > 0 - true
. Quindi esiste un tale modificatore di accesso. Allo 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;
}
}
GO TO FULL VERSION