چگونه یک متد
public native int getModifiers()
از یک کلاس Class
و چند ثابت از یک کلاس به هم مرتبط هستند Modifier
. فرض کنید یک کلاس داریم:
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، یا در سیستم دهم - 16. 16 در باینری = 00010000)
Modifier.PUBLIC
= 1 = 0000 0001Modifier.PRIVATE
= 2 = 0000 0010Modifier.PROTECTED
= 4 = 0000 0100Modifier.STATIC
= 8 = 0000 1000Modifier.FINAL
= 16 = 0001 0000Modifier.SYNCHRONIZED
= 32 = 0010 0000Modifier.VOLATILE
= 64 = 0100 0000Modifier.TRANSIENT
= 128 = 1000 0000Modifier.NATIVE
= 256 = 1 0000 0000Modifier.INTERFACE
= 512 = 10 0000 0000Modifier.ABSTRACT
= 1024 = 100 0000 0000NestedClass.class.getModifiers()
= 1033 = 100 0000 1001
getModifiers()
به این صورت محاسبه می شود که اگر یک کلاس حاوی یک اصلاح کننده دسترسی خاص باشد، همان بیتی که در اصلاح کننده دسترسی وجود دارد برابر با 1 می شود. در NestedClass
اصلاح کننده های دسترسی زیر: public
static
abstract
. یک PUBLIC
برابر با 0 رقم (دورترین فاصله به سمت راست) است. ب STATIC
- 3. ب 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: پاسخ 1024 است.
return
بازگشت خواهد شد true
، زیرا 1024 > 0 - true
. بنابراین چنین اصلاح کننده دسترسی وجود دارد. به همین ترتیب، این متد هم برای متدهای کلاس و هم برای فیلدهای کلاس قابل اعمال است. کد فیلد به شکل زیر خواهد بود:
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;
}
}
GO TO FULL VERSION