JavaRush /จาวาบล็อก /Random-TH /API การสะท้อน วิธีการทำงานของเมธอด getModifiers() ในคลาสค...
Георгий
ระดับ
Санкт-Петербург

API การสะท้อน วิธีการทำงานของเมธอด getModifiers() ในคลาสคลาส

เผยแพร่ในกลุ่ม
วิธีการpublic native int getModifiers()จากคลาสClassและค่าคงที่จากคลาส มี Modifierความ สัมพันธ์กันอย่างไร API การสะท้อน  วิธีการทำงานของเมธอด getModifiers() ในคลาส - 1สมมติว่าเรามีชั้นเรียน:
public static abstract class NestedClass{
}
วิธีการgetModifiers()ส่งกลับผลลัพธ์เป็นตัวเลขซึ่งมีการเข้ารหัสตัวแก้ไขการเข้าถึงของคลาสหรือวิธีการที่เรียกว่า หากต้องการเรียกgetModifiers()คลาส เช่น สำหรับคุณNestedClassต้องสร้างคลาสอ็อบเจ็กต์Classสำหรับคลาส NestedClassและClass<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()ดังตัวอย่างด้านบน A int specificModifierจะเท่ากับหนึ่งในค่าคงที่ของคลาสModifier: Modifier.PUBLICฯลฯ Modifier.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 1,000
  • Modifier.FINAL= 16 = 0001 0000
  • Modifier.SYNCHRONIZED= 32 = 0010 0000
  • Modifier.VOLATILE= 64 = 0100 0000
  • Modifier.TRANSIENT= 128 = 1,000 0000
  • Modifier.NATIVE= 256 = 1 0000 0000
  • Modifier.INTERFACE= 512 = 10 0000 0000
  • Modifier.ABSTRACT = 1,024 = 100 0000 0000
  • NestedClass.class.getModifiers()= 1,033 = 100 0000 1,001
และเราเห็นอะไร? สำหรับตัวแก้ไขแต่ละตัว จะมีการนำตัวเลขในวันที่ 10 มาใช้ ดังนั้นในวันที่ 2 1 ของตัวแก้ไขจะเลื่อนไปทางซ้ายหนึ่งตำแหน่ง และgetModifiers()มันถูกคำนวณในลักษณะที่ว่าหากคลาสมีตัวแก้ไขการเข้าถึงบางอย่าง บิตเดียวกันกับในตัวแก้ไขการเข้าถึงจะเท่ากับ 1 ในNestedClassตัวแก้ไขการเข้าถึงต่อไปนี้public static abstract: หนึ่งPUBLICมีค่าเท่ากับ 0 หลัก (ไปทางขวาสุด) B STATIC- 3. B ABSTRACT- 10. และตอนนี้เรามาดูของเราNestedClass.class.getModifiers(): ในตัวเลข 0, 3 และ 10 มีหนึ่งหลัก! และส่วนที่เหลือทั้งหมดเป็นศูนย์ ต่อไปเราจะดำเนินการแก้ไขปัญหาต่อไป เราต้องเข้าใจว่าgetModifiers()ตัวแก้ไขเฉพาะของเรามี หรือไม่ ลองพิจารณากรณีของตัวfinalแก้ไข Modifier.FINAL= 16 = 0001 0000 ดังนั้น หนึ่งจึงเท่ากับหลักที่ 4 จากการเปรียบเทียบกับตัวอย่างข้างต้น ลองดูว่าของเราNestedClass.class.getModifiers()= 100 0000 1001 หรือ Modifier.FINALไม่ ในที่นี้หลักที่ 4 เท่ากับ 0 ซึ่งหมายความว่าไม่มี ซึ่งเป็นจริง ( NestedClassไม่ใช่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: คำตอบคือ 1,024
ซึ่งหมายความว่าการแสดงออกของเราในreturnจะกลับมาtrueเพราะ 1024 > 0 - true. ดังนั้นจึงมีตัวแก้ไขการเข้าถึงดังกล่าว API การสะท้อน  วิธีการทำงานของเมธอด getModifiers() ในคลาส - 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