كيف ترتبط طريقة
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 = 00000001Modifier.PRIVATE
= 2 = 00000010Modifier.PROTECTED
= 4 = 00000100Modifier.STATIC
= 8 = 00001000Modifier.FINAL
= 16 = 00010000Modifier.SYNCHRONIZED
= 32 = 00100000Modifier.VOLATILE
= 64 = 01000000Modifier.TRANSIENT
= 128 = 10000000Modifier.NATIVE
= 256 = 100000000Modifier.INTERFACE
= 512 = 100000000Modifier.ABSTRACT
= 1024 = 10000000000NestedClass.class.getModifiers()
= 1033 = 10000001001
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، لذا فإن الواحد يساوي الرقم الرابع. قياسًا على المثال أعلاه، دعونا نرى ما إذا كان لدينا NestedClass.class.getModifiers()
= 100 0000 1001 Modifier.FINAL
. هنا الرقم الرابع يساوي 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 - الوحدات الموجودة في أقصى اليسار متطابقة. التحويل إلى العاشر: الجواب هو 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