JavaRush /Blog Java /Random-MS /API Refleksi. Cara kaedah getModifiers() berfungsi dalam ...
Георгий
Tahap
Санкт-Петербург

API Refleksi. Cara kaedah getModifiers() berfungsi dalam kelas Kelas

Diterbitkan dalam kumpulan
Bagaimana kaedah public native int getModifiers()daripada kelas Classdan beberapa pemalar daripada kelas berkaitan Modifier. API Refleksi.  Bagaimana kaedah getModifiers() berfungsi dalam Kelas - 1Katakan kita mempunyai kelas:
public static abstract class NestedClass{
}
Kaedah ini getModifiers()mengembalikan hasil sebagai nombor di mana pengubah suai akses kelas atau kaedah dari mana ia dipanggil disulitkan. Untuk memanggil getModifiers()kelas, contohnya untuk NestedClass, anda perlu mencipta objek kelas Classuntuk kelas NestedClass. Dan Class<NestedClass>panggil getModifiers().
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
Atau dalam satu baris dan paparkan hasilnya dan perwakilan binarinya:
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers));
Pada skrin:

classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001
Baiklah, tetapi mengapa nombor tertentu ini? Mari lihat contoh kelas NestedClass. Katakan kita mempunyai kaedah:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
Parameternya akan termasuk: int allModifiers = NestedClass.class.getModifiers(), seperti dalam contoh di atas. A int specificModifierakan sama dengan salah satu pemalar kelas Modifier: Modifier.PUBLIC, Modifier.STATICdsb. (kami akan mempertimbangkan baki pemalar di bawah). Dan kaedah itu akan kembali kepada kami truejika kelas mengandungi pengubah suai akses yang dihantar ke specificModifier. Jika tidak - false. Kod dalam kelas ujian akan kelihatan seperti ini:
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
Bagaimana untuk melaksanakan logik kaedah isModifierSet? Mari kita wakili pengubah dalam kelas dalam sistem binari Modifier: (contohnya, Modifier.FINAL= 0x00000010, atau dalam sistem ke-10 - 16. 16 dalam binari = 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
Dan apa yang kita lihat? Untuk setiap pengubah suai, nombor dalam ke-10 diambil supaya pada ke-2, 1 mereka bergerak satu tempat ke kiri. Dan getModifiers()ia dikira sedemikian rupa sehingga jika kelas mengandungi pengubah akses tertentu, maka bit yang sama seperti dalam pengubah akses menjadi sama dengan 1. Dalam NestedClasspengubah akses berikut: public static abstract. Satu PUBLICsama dengan 0 digit (paling jauh ke kanan). B STATIC- 3. B ABSTRACT- 10. Dan sekarang kita lihat pada kita NestedClass.class.getModifiers(): Dalam 0, 3 dan 10 digit ia mempunyai satu! Dan semua yang lain adalah sifar. Seterusnya kita teruskan untuk menyelesaikan masalah tersebut. Kita perlu memahami sama ada getModifiers()pengubah suai khusus kita mengandungi. Mari kita pertimbangkan kes untuk pengubah suai final. Modifier.FINAL= 16 = 0001 0000, jadi satu sama dengan digit ke-4. Dengan analogi dengan contoh di atas, mari kita lihat sama ada milik kita NestedClass.class.getModifiers()= 100 0000 1001 Modifier.FINAL. Di sini digit ke-4 adalah sama dengan 0. Ini bermakna ia tidak mengandungi, yang benar ( NestedClassbukan final). Tetapi logik apa yang harus saya tulis dalam kaedah? Kita perlu menggunakan nilai logik AND (&), iaitu 1 jika kedua-dua bit adalah 1. Jika tidak, 0. Kaedah kami akhirnya akan kelihatan seperti ini:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
        return (allModifiers & specificModifier) > 0;
    }
Mari pastikan kod berfungsi dan tunjukkan sebab ia berfungsi. Kami mengira NestedClass.class.getModifiers() & Modifier.FINAL:
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 000 0001 0000 - Modifier.FINAL(menambah 3 sifar ke kiri untuk kemudahan)
  • 000 0000 0000 - jawapan 0. Kami tidak mempunyai satu unit, kerana hanya 1 & 1 = 1. 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0;
Ini bermakna ungkapan kita dalam returnakan kembali false, kerana 0 > 0 - false. Ini bermakna tiada pengubah suai akses sedemikian. Mari lihat Modifier.ABSTRACT & NestedClass.class.getModifiers():
  • 100 0000 0000 -Modifier.ABSTRACT
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 100 0000 0000 - Unit paling kiri sepadan. Tukar kepada ke-10: jawapannya ialah 1024.
Ini bermakna ungkapan kita dalam returnakan kembali true, kerana 1024 > 0 - true. Jadi terdapat pengubah akses sedemikian. API Refleksi.  Bagaimana kaedah getModifiers() berfungsi dalam Kelas - 2Dengan cara yang sama, kaedah ini boleh digunakan untuk kedua-dua kaedah kelas dan medan kelas. Kod untuk medan akan kelihatan seperti ini:
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;
    }
}
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION