getModifiers()方法如何计算多个修饰符的值?

Bac*_*ria 7 java

getModifiers()的Java Doc 如下:

int getModifiers()

以整数形式返回此Member表示的成员或构造函数的Java语言修饰符.应使用Modifier类来解码整数中的修饰符.

和Java Docs还提供了不同修饰符及其对应的int值列表:

public static final int ABSTRACT 1024

public static final int FINAL 16

public static final int INTERFACE 512

public static final int NATIVE 256

public static final int PRIVATE 2

public static final int PROTECTED 4

public static final int PUBLIC 1

public static final int STATIC 8

public static final int STRICT 2048

public static final int SYNCHRONIZED 32

public static final int TRANSIENT 128

public static final int VOLATILE 64

对于单个修饰符,getModifiers()非常简单.它只返回对应于修饰符的常量值(例如,当我将一个类声明为public final并调用getModifiers()时,它返回17).

System.out.println("modifierValue:" + MyClass.class.getModifiers());
Run Code Online (Sandbox Code Playgroud)

输出是:

17
Run Code Online (Sandbox Code Playgroud)

但是,我不太明白它如何适用于多个修饰符.任何人都可以开导我吗?

Bor*_*der 14

TL; DR:它将它们加在一起形成一个位字段.

要理解这一点,你需要了解二进制如何工作,这类似于十进制 - 让我们从那里开始:

 1    - public
 10   - static
 100  - final
Run Code Online (Sandbox Code Playgroud)

那么,101意味着什么?必须是public final因为除了单个100和单个之外,十进制系统中没有其他方法可以制作"一百零一" 1.

现在将其扩展为二进制:

1 - public
2 - private
4 - protected
8 - static
Run Code Online (Sandbox Code Playgroud)

9意味着什么?好吧,与十进制系统一样,只有一种(正确的)9二进制方式 - 一8和一1.

现在我们使用我们称之为位域9的二进制文件:

1001
Run Code Online (Sandbox Code Playgroud)

要验证,写一些代码!

public static void main(String[] args) throws Exception {
    int i = 9;
    System.out.println(Integer.toBinaryString(i));
}
Run Code Online (Sandbox Code Playgroud)

现在,使用十进制系统,我们将10重复除以并检查最右边的数字(最不重要).对于二进制,这个过程是相同的,除了我们除以2- 这称为位移.

public static void main(String[] args) throws Exception {
    int i = 9;
    System.out.println(Integer.toBinaryString(i));
    i >>= 1;
    System.out.println(Integer.toBinaryString(i));
    i >>= 1;
    System.out.println(Integer.toBinaryString(i));
    i >>= 1;
    System.out.println(Integer.toBinaryString(i));
}
Run Code Online (Sandbox Code Playgroud)

输出:

1001
100
10
1
Run Code Online (Sandbox Code Playgroud)

所以,如果我知道这private是2 1的值,并且我们知道我们有多少位,所有只需要移位正确的位数并采用模数2:

public static void main(String[] args) throws Exception {
    int i = 9;
    i >>= 2;
    System.out.println(i%2);
}
Run Code Online (Sandbox Code Playgroud)

输出:

0
Run Code Online (Sandbox Code Playgroud)

所以我们基本上使用组成二进制数字的10值来存储布尔值.

所以把这个例子带入阅读世界:

public static void main(String[] args) throws Exception {
    final Method method = App.class.getMethod("myMethod");
    final int modifiers = method.getModifiers();
    System.out.println(modifiers);
    System.out.println(Integer.toBinaryString(modifiers));
}

public strictfp synchronized static final void myMethod() {

}
Run Code Online (Sandbox Code Playgroud)

输出:

2105
100000111001
Run Code Online (Sandbox Code Playgroud)

所以我们可以看到我们有:

2 0 = 1 - true
2 1 = 2 - false
2 2 = 4 - false
2 3 = 8 - true
2 4 = 16 - true
2 5 = 32 - true
2 7 = 64 - false
2 8 = 128 - false
2 9 = 256 - false
2 10 = 512 - false
2 11 = 1024 - false
2 12 = 2048 -true