JavaRush /Java Blog /Random-JA /リフレクション API。Class クラスでの getModifiers() メソッドの動作
Георгий
レベル 22
Санкт-Петербург

リフレクション API。Class クラスでの getModifiers() メソッドの動作

Random-JA グループに公開済み
public native int getModifiers()クラスの メソッドClassとクラスの一部の定数の関係Modifierリフレクション API。 クラス 1 での getModifiers() メソッドの動作方法クラスがあるとします。
public static abstract class NestedClass{
}
このメソッドは、getModifiers()呼び出し元のクラスまたはメソッドのアクセス修飾子が暗号化された結果を数値として返します。getModifiers()たとえば for クラスを呼び出すには、 class のNestedClassクラス オブジェクトを作成する必要があります。そしてに電話してください。 ClassNestedClassClass<NestedClass>getModifiers()
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
または、結果とそのバイナリ表現を 1 行で表示します。
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()上の例のように、 パラメータには次のものが含まれます 。A はint specificModifierクラス定数の 1 つと等しくなります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? クラス内の修飾子を 2 進数で表してみましょうModifier: (たとえば、Modifier.FINAL= 0x00000010、または 10 番目の体系では - 16. 16 (2 進数 = 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 が 1 つ左に移動します。また、getModifiers()クラスに特定のアクセス修飾子が含まれている場合、そのアクセス修飾子と同じビットが 1 に等しくなるように計算されます。NestedClass次のアクセス修飾子では、public static abstract. 1 はPUBLIC0 桁 (一番右) に相当します。B STATIC- 3. B ABSTRACT- 10. そして今、私たちの数字を見てみますNestedClass.class.getModifiers()。0、3、10 の数字には 1 があります。そして残りはすべてゼロです。次に問題の解決に進みます。特定の修飾子に が含まれているかどうかを理解する必要がありますgetModifiers()。修飾子 の場合を考えてみましょうfinalModifier.FINAL= 16 = 0001 0000 なので、1 は 4 桁目に相当します。上の例から類推して、 ours 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 のみ。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。 クラス 2 での getModifiers() メソッドの仕組み同様に、このメソッドはクラス メソッドとクラス フィールドの両方に適用できます。フィールドのコードは次のようになります。
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