JavaRush /Java Blog /Random-KO /반사 API. Class 클래스에서 getModifiers() 메서드가 작동하는 방식
Георгий
레벨 22
Санкт-Петербург

반사 API. Class 클래스에서 getModifiers() 메서드가 작동하는 방식

Random-KO 그룹에 게시되었습니다
public native int getModifiers()클래스의 메서드 Class와 클래스의 일부 상수가 어떻게 관련되어 있습니까 Modifier? 반사 API.  클래스 - 1에서 getModifiers() 메소드가 작동하는 방식수업이 있다고 가정해 보겠습니다.
public static abstract class NestedClass{
}
이 메서드는 getModifiers()호출된 클래스 또는 메서드의 액세스 한정자가 암호화된 숫자로 결과를 반환합니다. getModifiers()예를 들어 클래스를 호출하려면 해당 클래스에 대한 NestedClass클래스 개체를 만들어야 합니다 . 그리고 전화하세요 . ClassNestedClassClass<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 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이 왼쪽으로 한 칸 이동합니다. 그리고 getModifiers()클래스에 특정 액세스 한정자가 포함된 경우 액세스 한정자와 동일한 비트가 1이 되는 방식으로 계산됩니다. NestedClass다음 액세스 한정자 에서는 public static abstract. 1 PUBLIC은 0자리(가장 오른쪽)과 같습니다. B STATIC- 3. B ABSTRACT- 10. 이제 우리의 숫자를 살펴보겠습니다 NestedClass.class.getModifiers(). 0, 3, 10 숫자에는 하나가 있습니다! 나머지는 모두 0입니다. 다음으로 문제 해결로 넘어갑니다. 특정 수정자가 포함되어 있는지 이해해야 합니다 getModifiers(). modifier 의 경우를 고려해 봅시다 final. Modifier.FINAL= 16 = 0001 0000이므로 1은 4번째 자리와 같습니다. NestedClass.class.getModifiers()위의 예와 유사하게 우리의 값이 100 0000 1001 인지 확인해 보겠습니다 Modifier.FINAL. 여기서 네 번째 숫자는 0과 같습니다. 이는 포함하지 않음을 의미하며 이는 사실입니다( NestedClassnot final). 그런데 메소드에 어떤 로직을 작성해야 할까요? 두 비트가 모두 1이면 1인 논리값을 적용해야 합니다 AND (&). 그렇지 않으면 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(편의를 위해 왼쪽에 0 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번째로 변환하면 답은 1024입니다.
이는 의 표현식이 를 return반환할 것임을 의미합니다 true. 왜냐하면 1024 > 0 - true. 그래서 그러한 접근 수정자가 있습니다. 반사 API.  Class - 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