Wie eine Methode
public native int getModifiers()
einer Klasse Class
und einige Konstanten einer Klasse zusammenhängen Modifier
. Nehmen wir an, wir haben eine Klasse:
public static abstract class NestedClass{
}
Die Methode getModifiers()
gibt das Ergebnis als Zahl zurück, in der die Zugriffsmodifikatoren der Klasse oder Methode, von der sie aufgerufen wird, verschlüsselt sind. Um eine Klasse aufzurufen getModifiers()
, beispielsweise für NestedClass
, müssen Sie ein Klassenobjekt Class
für die Klasse erstellen NestedClass
. Und Class<NestedClass>
Ruf an getModifiers()
.
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
Oder in einer Zeile und zeigen Sie das Ergebnis und seine binäre Darstellung an:
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers));
Auf dem Bildschirm:
classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001
Okay, aber warum gerade diese Zahl? Schauen wir uns das Beispiel der Klasse an NestedClass
. Nehmen wir an, wir haben eine Methode:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
Zu seinen Parametern gehören: int allModifiers = NestedClass.class.getModifiers()
, wie im obigen Beispiel. A int specificModifier
entspricht einer der Klassenkonstanten Modifier
: Modifier.PUBLIC
usw. Modifier.STATIC
(Die übrigen Konstanten betrachten wir weiter unten). Und die Methode kehrt zu uns zurück true
, wenn die Klasse den an übergebenen Zugriffsmodifikator enthält specificModifier
. Wenn nicht - false
. Der Code in der Testklasse sieht folgendermaßen aus:
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
Wie implementiert man die Logik der Methode isModifierSet
? Stellen wir Modifikatoren in der Klasse im Binärsystem dar Modifier
: (zum Beispiel Modifier.FINAL
= 0x00000010 oder im 10. System - 16. 16 im Binärsystem = 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()
es wird so berechnet, dass, wenn eine Klasse einen bestimmten Zugriffsmodifikator enthält, dasselbe Bit wie im Zugriffsmodifikator gleich 1 wird. In NestedClass
den folgenden Zugriffsmodifikatoren: public
static
abstract
. Eins PUBLIC
entspricht der Ziffer 0 (am weitesten rechts). B STATIC
- 3. B ABSTRACT
- 10. Und jetzt schauen wir uns unsere an NestedClass.class.getModifiers()
: In den Ziffern 0, 3 und 10 steht eins! Und alle anderen sind Null. Als nächstes gehen wir zur Lösung des Problems über. Wir müssen verstehen, ob unser getModifiers()
spezifischer Modifikator enthält. Betrachten wir den Fall für den Modifikator final
. Modifier.FINAL
= 16 = 0001 0000, also ist eins gleich der 4. Ziffer. Schauen wir uns analog zum obigen Beispiel an, ob unsere NestedClass.class.getModifiers()
= 100 0000 1001 ist Modifier.FINAL
. Hier ist die 4. Ziffer gleich 0. Dies bedeutet, dass sie nicht enthält, was wahr ist ( NestedClass
nicht final
). Aber welche Logik soll ich in die Methode schreiben? Wir müssen einen logischen Wert anwenden AND (&)
, der 1 ist, wenn beide Bits 1 sind. Andernfalls 0. Unsere Methode wird schließlich so aussehen:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
return (allModifiers & specificModifier) > 0;
}
Stellen wir sicher, dass der Code funktioniert, und zeigen wir, warum er funktioniert. Wir berechnen NestedClass.class.getModifiers() & Modifier.FINAL
:
- 100 0000 1001 -
NestedClass.class.getModifiers()
- 000 0001 0000 –
Modifier.FINAL
(der Einfachheit halber wurden links drei Nullen hinzugefügt) - 000 0000 0000 - Antwort 0. Wir haben keine einzige Einheit, weil nur 1 & 1 = 1. 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0;
return
will return false
, weil 0 > 0 - false
. Dies bedeutet, dass es keinen solchen Zugriffsmodifikator gibt. Lass uns nachsehen Modifier.ABSTRACT & NestedClass.class.getModifiers()
:
- 100 0000 0000 -
Modifier.ABSTRACT
- 100 0000 1001 -
NestedClass.class.getModifiers()
- 100 0000 0000 – Die Einheiten ganz links, die übereinstimmen. In 10. umrechnen: Die Antwort ist 1024.
return
will return true
, weil 1024 > 0 - true
. Es gibt also einen solchen Zugriffsmodifikator. Auf die gleiche Weise kann diese Methode sowohl auf Klassenmethoden als auch auf Klassenfelder angewendet werden. Der Code für das Feld sieht folgendermaßen aus:
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