JavaRush /Java 博客 /Random-ZH /反射 API。getModifiers() 方法在 Class 类中如何工作
Георгий
第 22 级
Санкт-Петербург

反射 API。getModifiers() 方法在 Class 类中如何工作

已在 Random-ZH 群组中发布
public native int getModifiers()类中的 方法Class和类中的某些常量如何相关Modifier反射 API。 getModifiers() 方法在 Class - 1 中的工作原理假设我们有一堂课:
public static abstract class NestedClass{
}
该方法getModifiers()以数字形式返回结果,其中调用该方法的类或方法的访问修饰符已加密。要调用getModifiers()一个类,例如 for ,您需要为该类NestedClass创建一个类对象。并打电话。 ClassNestedClassClass<NestedClass>getModifiers()
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
或者在一行中显示结果及其二进制表示形式:
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers));
屏幕上:

classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001
好的,但是为什么是这个特定的数字呢?我们来看一下类的例子NestedClass。假设我们有一个方法:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
其参数将包括: int allModifiers = NestedClass.class.getModifiers(),如上例所示。Aint specificModifier将等于类常量之一Modifier:等Modifier.PUBLICModifier.STATIC(我们将在下面考虑其余的常数)。true如果该类包含传递给 的访问修饰符,该方法将返回给我们specificModifier。如果不 - false。测试类中的代码将如下所示:
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
如何实现该方法的逻辑isModifierSet?让我们用二进制表示类中的修饰符Modifier:(例如Modifier.FINAL= 0x00000010,或在 10 进制中 - 16。二进制中的 16 = 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
我们看到了什么?对于每个修饰符,在第 10 个修饰符中取一个数字,以便在第 2 个修饰符中,它们的 1 向左移动一位。它getModifiers()的计算方式是,如果一个类包含某个访问修饰符,那么与该访问修饰符中相同的位就等于 1。在NestedClass以下访问修饰符中:public static abstract。1PUBLIC等于 0 数字(最右边)。B STATIC- 3。B ABSTRACT- 10。现在我们看看我们的NestedClass.class.getModifiers():在 0、3 和 10 数字中,它有 1!其余的全部为零。接下来我们继续解决问题。我们需要了解我们的getModifiers()特定修饰符是否包含。让我们考虑一下修饰符的情况finalModifier.FINAL= 16 = 0001 0000,所以 1 等于第 4 位数字。类比上面的例子,我们看看我们的是否NestedClass.class.getModifiers()= 100 0000 1001 Modifier.FINAL。这里第 4 位数字等于 0。这意味着它不包含,这是 true ( NestedClassnot final)。但是方法中应该写什么逻辑呢?我们需要应用一个逻辑值AND (&),如果两个位都为 1,则为 1。否则为 0。我们的方法最终将如下所示:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
        return (allModifiers & specificModifier) > 0;
    }
让我们确保代码可以工作并展示它为什么可以工作。我们计算NestedClass.class.getModifiers() & Modifier.FINAL
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 000 0001 0000 - Modifier.FINAL(为方便起见,在左侧添加了 3 个零)
  • 000 0000 0000 - 回答 0。我们没有一个单位,因为 只有 1 & 1 = 1。1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0;
这意味着我们的表达式return将返回false,因为 0 > 0 - false. 这意味着不存在这样的访问修饰符。我们看看吧Modifier.ABSTRACT & NestedClass.class.getModifiers()
  • 100 0000 0000 -Modifier.ABSTRACT
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 100 0000 0000 - 最左边的单位匹配。转换为第 10 次:答案是 1024。
这意味着我们的表达式return将返回true,因为 1024 > 0 - true. 这意味着存在这样的访问修饰符。 反射 API。 getModifiers() 方法在 Class - 2 中的工作原理同样,该方法既可以应用于类方法,也可以应用于类字段。该字段的代码如下所示:
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;
    }
}
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION