JavaRush /Blog Java /Random-VI /API phản ánh. Cách thức hoạt động của phương thức getModi...
Георгий
Mức độ
Санкт-Петербург

API phản ánh. Cách thức hoạt động của phương thức getModifiers() trong lớp Class

Xuất bản trong nhóm
Mối liên hệ giữa một phương thức public native int getModifiers()của một lớp Classvà một số hằng số trong một lớp Modifier. API phản ánh.  Cách hoạt động của phương thức getModifiers() trong Lớp - 1Giả sử chúng ta có một lớp:
public static abstract class NestedClass{
}
Phương thức này getModifiers()trả về kết quả dưới dạng một số trong đó các bộ sửa đổi truy cập của lớp hoặc phương thức mà nó được gọi được mã hóa. Để gọi getModifiers()một lớp, chẳng hạn như NestedClass, bạn cần tạo một đối tượng lớp Classcho lớp NestedClass. Và Class<NestedClass>gọi getModifiers().
Class<NestedClass> c = NestedClass.class;
int classModifiers = c.getModifiers();
Hoặc trong một dòng và hiển thị kết quả và biểu diễn nhị phân của nó:
int classModifiers = NestedClass.class.getModifiers();
System.out.printf("classModifier = %d%n",classModifiers);
System.out.printf("classModifier в двоичной системе счисления = %s%n",Integer.toBinaryString(classModifiers));
Trên màn hình:

classModifiers = 1033
classModifiers в двоичной системе счисления = 10000001001
Được rồi, nhưng tại sao lại có con số cụ thể này? Hãy xem ví dụ của lớp NestedClass. Giả sử chúng ta có một phương pháp:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
}
Các tham số của nó sẽ bao gồm: int allModifiers = NestedClass.class.getModifiers(), như trong ví dụ trên. A int specificModifiersẽ bằng một trong các hằng số lớp Modifier: Modifier.PUBLIC, Modifier.STATICv.v. (chúng ta sẽ xem xét các hằng số còn lại bên dưới). Và phương thức sẽ trả về cho chúng ta truenếu lớp chứa bộ sửa đổi truy cập được truyền cho specificModifier. Nếu không - false. Mã trong lớp kiểm tra sẽ trông như thế này:
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
Làm thế nào để thực hiện logic của phương pháp isModifierSet? Hãy biểu diễn các từ bổ nghĩa trong lớp trong hệ nhị phân Modifier: (ví dụ: Modifier.FINAL= 0x00000010 hoặc trong hệ thứ 10 - 16. 16 ở dạng nhị phân = 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
Và chúng ta thấy gì? Đối với mỗi bổ nghĩa, một số ở số 10 được lấy để ở số 2, số 1 của chúng di chuyển sang trái một vị trí. Và getModifiers()nó được tính theo cách mà nếu một lớp chứa một bộ sửa đổi truy cập nhất định thì bit tương tự như trong bộ sửa đổi truy cập sẽ bằng 1. Trong NestedClasscác bộ sửa đổi truy cập sau: public static abstract. Một PUBLICbằng chữ số 0 (xa nhất về bên phải). B STATIC- 3. B ABSTRACT- 10. Và bây giờ chúng ta nhìn vào số của chúng ta NestedClass.class.getModifiers(): Trong các chữ số 0, 3 và 10 nó có một! Và tất cả những thứ còn lại đều bằng không. Tiếp theo chúng ta chuyển sang giải quyết vấn đề. Chúng ta cần hiểu liệu getModifiers()công cụ sửa đổi cụ thể của chúng ta có chứa hay không. Hãy xem xét trường hợp của công cụ sửa đổi final. Modifier.FINAL= 16 = 0001 0000, nên một bằng chữ số thứ 4. Bằng cách tương tự với ví dụ trên, hãy xem liệu của chúng ta có NestedClass.class.getModifiers()= 100 0000 1001 hay không Modifier.FINAL. Ở đây chữ số thứ 4 bằng 0. Điều này có nghĩa là nó không chứa, điều này đúng ( NestedClasskhông final). Nhưng tôi nên viết logic gì trong phương pháp này? Chúng ta cần áp dụng một giá trị logic AND (&), là 1 nếu cả hai bit đều là 1. Nếu không thì là 0. Phương thức của chúng ta cuối cùng sẽ trông như thế này:
public static boolean isModifierSet(int allModifiers, int specificModifier) {
        return (allModifiers & specificModifier) > 0;
    }
Hãy đảm bảo mã hoạt động và cho biết lý do tại sao nó hoạt động. Chúng tôi tính toán NestedClass.class.getModifiers() & Modifier.FINAL:
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 000 0001 0000 - Modifier.FINAL(thêm 3 số 0 vào bên trái cho tiện)
  • 000 0000 0000 - trả lời 0. Chúng tôi không có một đơn vị duy nhất, bởi vì chỉ 1 & 1 = 1. 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0;
Điều này có nghĩa là biểu thức của chúng ta trong returnsẽ trả về false, bởi vì 0 > 0 - false. Điều này có nghĩa là không có công cụ sửa đổi truy cập như vậy. Hãy xem Modifier.ABSTRACT & NestedClass.class.getModifiers():
  • 100 0000 0000 -Modifier.ABSTRACT
  • 100 0000 1001 -NestedClass.class.getModifiers()
  • 100 0000 0000 - Các đơn vị ngoài cùng bên trái khớp. Chuyển sang số 10: đáp án là 1024.
Điều này có nghĩa là biểu thức của chúng ta trong returnsẽ trả về true, bởi vì 1024 > 0 - true. Vì vậy, có một công cụ sửa đổi truy cập như vậy. API phản ánh.  Cách hoạt động của phương thức getModifiers() trong Lớp - 2Theo cách tương tự, phương thức này có thể được áp dụng cho cả phương thức lớp và trường lớp. Mã cho trường sẽ trông như thế này:
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;
    }
}
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION