How a method
public native int getModifiers()
from a class Class
and some constants from a class are related Modifier
. Let's say we have a class:
public static abstract class NestedClass{
}
The method getModifiers()
returns the result as a number in which the access modifiers of the class or method from which it is called are encrypted. To call on getModifiers()
a class, for example for NestedClass
, you need to create a class object Class
for the class NestedClass
. And Class<NestedClass>
call getModifiers()
.
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
Or in one line and display the result and its binary representation:
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers));
On the screen:
classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001
Okay, but why this particular number? Let's look at the example of the class NestedClass
. Let's say we have a method:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
Its parameters will include: int allModifiers = NestedClass.class.getModifiers()
, as in the example above. A int specificModifier
will be equal to one of the class constants Modifier
: Modifier.PUBLIC
, Modifier.STATIC
etc. (we will consider the remaining constants below). And the method will return to us true
if the class contains the access modifier passed to specificModifier
. If not - false
. The code in the test class will look like this:
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
How to implement the logic of the method isModifierSet
? Let's represent modifiers in the class in the binary system Modifier
: (for example, Modifier.FINAL
= 0x00000010, or in the 10th system - 16. 16 in binary = 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()
it is calculated in such a way that if a class contains a certain access modifier, then the same bit as in the access modifier becomes equal to 1. In NestedClass
the following access modifiers: public
static
abstract
. One PUBLIC
is equal to 0 digit (farthest to the right). B STATIC
- 3. B ABSTRACT
- 10. And now we look at ours NestedClass.class.getModifiers()
: In the 0, 3 and 10 digits it has one! And all the rest are zero. Next we move on to solving the problem. We need to understand whether our getModifiers()
specific modifier contains. Let's consider the case for the modifier final
. Modifier.FINAL
= 16 = 0001 0000, so one is equal to the 4th digit. By analogy with the example above, let’s see if ours NestedClass.class.getModifiers()
= 100 0000 1001 Modifier.FINAL
. Here the 4th digit is equal to 0. This means it does not contain, which is true ( NestedClass
not final
). But what logic should I write in the method? We need to apply a logical value AND (&)
, which is 1 if both bits are 1. Otherwise, 0. Our method will finally look like this:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
return (allModifiers & specificModifier) > 0;
}
Let's make sure the code works and show why it works. We calculate NestedClass.class.getModifiers() & Modifier.FINAL
:
- 100 0000 1001 -
NestedClass.class.getModifiers()
- 000 0001 0000 -
Modifier.FINAL
(added 3 zeros to the left for convenience) - 000 0000 0000 - answer 0. We don’t have a single unit, because only 1 & 1 = 1. 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0;
return
will return false
, because 0 > 0 - false
. This means there is no such access modifier. Let's look Modifier.ABSTRACT & NestedClass.class.getModifiers()
:
- 100 0000 0000 -
Modifier.ABSTRACT
- 100 0000 1001 -
NestedClass.class.getModifiers()
- 100 0000 0000 - The leftmost units matched. Convert to 10th: the answer is 1024.
return
will return true
, because 1024 > 0 - true
. So there is such an access modifier. In the same way, this method can be applied to both class methods and class fields. The code for the field will look like this:
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