JavaRush /Blog Java /Random-PL /API refleksji. Jak działa metoda getModifiers() w klasie ...
Георгий
Poziom 22
Санкт-Петербург

API refleksji. Jak działa metoda getModifiers() w klasie Class

Opublikowano w grupie Random-PL
W jaki sposób metoda public native int getModifiers()z klasy Classi niektóre stałe z klasy są ze sobą powiązane Modifier. API refleksji.  Jak działa metoda getModifiers() w klasie - 1Powiedzmy, że mamy klasę:
public static abstract class NestedClass{
}
Metoda getModifiers()zwraca wynik w postaci liczby, w której zaszyfrowane są modyfikatory dostępu klasy lub metody, z której jest wywoływana. Aby wywołać getModifiers()klasę, na przykład dla NestedClass, musisz utworzyć obiekt klasy Classdla tej klasy NestedClass. I Class<NestedClass>zadzwoń getModifiers().
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
Lub w jednym wierszu i wyświetl wynik i jego reprezentację binarną:
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers));
Na ekranie:

classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001
OK, ale dlaczego akurat ten numer? Spójrzmy na przykład klasy NestedClass. Powiedzmy, że mamy metodę:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
Jego parametrami będą m.in.: int allModifiers = NestedClass.class.getModifiers(), jak w powyższym przykładzie. A int specificModifierbędzie równe jednej ze stałych klasy Modifier: Modifier.PUBLIC, Modifier.STATICitd. (pozostałe stałe rozważymy poniżej). A metoda wróci do nas, truejeśli klasa zawiera modyfikator dostępu przekazany do specificModifier. Jeśli nie - false. Kod w klasie testowej będzie wyglądał następująco:
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
Jak wdrożyć logikę metody isModifierSet? Przedstawmy modyfikatory w klasie w systemie binarnym Modifier: (na przykład Modifier.FINAL= 0x00000010, lub w systemie 10. - 16,16 w systemie binarnym = 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
I co widzimy? Dla każdego modyfikatora pobierana jest liczba z 10., tak że w 2. ich 1 przesuwa się o jedno miejsce w lewo. I getModifiers()jest to obliczane w ten sposób, że jeśli klasa zawiera pewien modyfikator dostępu, to ten sam bit co w modyfikatorze dostępu staje się równy 1. W NestedClassnastępujących modyfikatorach dostępu: public static abstract. Jeden PUBLICjest równy 0 cyfrom (najbardziej na prawo). B STATIC- 3. B ABSTRACT- 10. A teraz spójrzmy na nasze NestedClass.class.getModifiers(): W cyfrach 0, 3 i 10 ma jedną! A cała reszta to zero. Następnie przechodzimy do rozwiązania problemu. Musimy zrozumieć, czy nasz getModifiers()konkretny modyfikator zawiera. Rozważmy przypadek modyfikatora final. Modifier.FINAL= 16 = 0001 0000, więc jeden jest równy czwartej cyfrze. Analogicznie do powyższego przykładu, zobaczmy, czy nasze NestedClass.class.getModifiers()= 100 0000 1001 Modifier.FINAL. Tutaj czwarta cyfra jest równa 0. Oznacza to, że nie zawiera, co jest prawdą ( NestedClassnie final). Ale jaką logikę mam napisać w metodzie? Musimy zastosować wartość logiczną AND (&), która wynosi 1, jeśli oba bity mają wartość 1. W przeciwnym razie 0. Nasza metoda ostatecznie będzie wyglądać następująco:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
        return (allModifiers & specificModifier) > 0;
    }
Upewnijmy się, że kod działa i pokażmy, dlaczego działa. Obliczamy NestedClass.class.getModifiers() & Modifier.FINAL:
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 000 0001 0000 - Modifier.FINAL(dla wygody dodano 3 zera po lewej stronie)
  • 000 0000 0000 - odpowiedź 0. Nie mamy ani jednej jednostki, bo tylko 1 i 1 = 1. 1 i 0 = 0, 0 i 1 = 0, 0 i 0 = 0;
Oznacza to, że nasze wyrażenie in returnzwróci false, ponieważ 0 > 0 - false. Oznacza to, że nie ma takiego modyfikatora dostępu. Spójrzmy Modifier.ABSTRACT & NestedClass.class.getModifiers():
  • 100 0000 0000 -Modifier.ABSTRACT
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 100 0000 0000 — Dopasowano jednostki skrajnie lewe. Zamień na 10: odpowiedź to 1024.
Oznacza to, że nasze wyrażenie in returnzwróci true, ponieważ 1024 > 0 - true. Istnieje więc taki modyfikator dostępu. API refleksji.  Jak działa metoda getModifiers() w klasie - 2W ten sam sposób metodę tę można zastosować zarówno do metod klas, jak i pól klas. Kod pola będzie wyglądał następująco:
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;
    }
}
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION