1. مقدمة
انعكاس Java هو آلية تسمح لنا بالحصول على معلومات داخلية عن أساليب الفصل ، والخصائص ، والطبقات الأم ، والواجهات ، وما إلى ذلك في وقت التشغيل. بمعنى آخر ، الانعكاس هو في الأساس عملية "عكسية". عندما نقوم بإنشاء مثيل لفئة من خلال new ، يتم تصميمه فعليًا بواسطة الجهاز الظاهري Java استنادًا إلى كائن Class من هذه الفئة في وقت التشغيل ، والانعكاس هو الحصول على معلومات التعريف الخاصة به من خلال كائن Class لفئة ما ، حتى نتمكن من الوصول إلى خصائصه وأساليبها ، ومعرفة الفئة الأم لهذه الفئة ، والتي يتم تنفيذ واجهات ، وغيرها من المعلومات.
2. الفصل
نحن نعلم أنه يمكن استخدام Javac تجميع ملفات .java في ملفات .class ، والتي تحتوي على معلومات التعريف الأصلية الخاصة بنا للفئة (فئة الوالدين ، واجهة ، مُنشئ ، خصائص ، طرق ، إلخ). سيتم تحميل ملف .class في جهاز Java Virtual Machine (JVM) ClassLoader في وقت التشغيل. عند تحميل ملف .class ، ستقوم JVM بإنشاء كائن فئة له. يتم بالفعل إنشاء الكائنات التي نستند إليها من خلال الجديد في البرنامج بناءً على كائن الفئة المقابل في وقت التشغيل. لكي نكون دقيقًا ، يعد كائن الفئة هذا في الواقع مثيلًا للفئة العامة java.lang.Class<T> . على سبيل المثال ، فإن كائن Class<MyClass> عبارة عن Class<T> مثيل يلف معلومات تعريف فئة MyClass . نظرًا لأن فئة java.lang.Class<T> لا تحتوي على مُنشئ عام ، لا يمكننا إنشاء إنشاء هذه الفئة مباشرة. يمكننا الحصول على كائن فئة من خلال الطريقة التالية.
في التفسير التالي ، سنأخذ فصل درس الناس ودرس الطلاب كأمثلة:
الفئة العامة الناس {اسم السلسلة الخاصة ؛ عصر INT الخاص ؛ الناس العامة (اسم السلسلة ، int age) {this.name = name ؛ this.age = العمر ؛ } public int getage () {return Age ؛ } السلسلة العامة getName () {return name ؛ } public void setage (int age) {this.age = age ؛ } public void setName (اسم السلسلة) {this.name = name ؛ } public void Speak () {system.out.println (getName () + "" + getage ()) ؛ }} طالب الفئة العامة يمتد الأشخاص {private int grade ؛ الطالب العام (اسم السلسلة ، int Age) {Super (name ، Age) ؛ } الطالب العام (اسم السلسلة ، int ، int grade) {super (name ، age) ؛ this.grade = grade ؛ } public int getGrade () {return Grade ؛ } public void setgrade (int grade) {this.grade = grade ؛ } private void Learn (String Course) {System.out.println (name + "Learn" + Course) ؛ }} احصل على كائن الفصل حسب اسم الفصل
إذا عرفنا اسم الفصل خلال فترة التجميع ، فيمكننا الحصول على كائن الفصل مثل هذا:
فئة <people> peopleclass = people.class ؛
هناك أيضًا طريقة للحصول على كائنات فئة بناءً على اسم المسار الكامل للفئة على النحو التالي:
// لنفترض أن فئة الناس موجودة في فئة حزمة com.test <people> peopleclass = class.forname ("com.test.people") ؛ لاحظ أن معلمة طريقة Class.forName() يجب أن تكون اسم المسار الكامل للفئة. في الواقع ، طالما أننا "استيراد com.test.people" ، يمكننا الحصول مباشرة على كائن الفصل من خلال " People.class " دون الحاجة إلى كتابة المسار الكامل. (إذا لم يتم العثور على الفئة المقابلة في classpath عند استدعاء طريقة Class.forName() ، فسيتم طرح ClassNotFoundException .)
احصل على كائن الفئة من خلال الكائن نفسه
الناس = أشخاص جدد ("بيل" ، 18) ؛ فئة <people> peopleclass = people.getClass () ؛ احصل على مُنشئ الفصل
بمجرد الحصول على كائن فئة People ، يمكننا الحصول على معلومات التعريف الأصلية لفئة People من خلال هذا الكائن الفئة. أولاً ، دعنا نحصل على كائن مُنشئ فئة People . مع كائن المنشئ هذا ، يمكننا بناء كائن People . على سبيل المثال ، يمكننا إضافة الكود التالي في student.java:
public static void main (string [] args) {class <people> pClass = people.class ؛ Try {Constructor <People> Constructor = pClass.getContructor (string.class ، int.class) ؛ الناس الناس = مُنشئ. newinstance ("Bill" ، 18) ؛ obj.speak () ؛ } catch (استثناء e) {}} في ما سبق ، ندعو طريقة getConstructor للحصول على كائن مُنشئ لفئة People . نظرًا لأن المنشئ نريد الحصول على المعلمات الرسمية String النوع و int ، فإننا نمر في String.class و int.class . باستخدام كائن المنشئ ، يمكننا استدعاء طريقة newInstance لإنشاء كائن people .
لاحظ أنه عندما يتم الحصول على كائنات Constructor Method Field من خلال الانعكاس ، قبل استدعاء طرق هذه الكائنات ، يتم ضبط العلامة accessible لهذا الكائن على true لإلغاء فحص الوصول إلى لغة Java ، والتي يمكن أن تحسن سرعة الانعكاس. كما هو موضح في الكود التالي:
مُنشئ <people> constructor = peopleclass.getConstructor (string.class ، int.class) ؛ // قم بتعيين الخاصية التي يمكن الوصول إليها من المنشئ إلى ture لإلغاء Java Check Conversor.setAccible (true) ؛
الحصول على أساليب إعلان في الفصل من خلال التفكير
احصل على الطريقة المعلنة في الفئة الحالية (باستثناء موروثة من فئة الأصل)
لإعلان جميع الطرق في الفصل الحالي ، يمكنك استخدام وظيفة getDeclaredMethods في الفصل. ستحصل على جميع الأساليب المعلنة في الفصل الحالي (بما في ذلك الأساليب private public static وغيرها). سيعود مجموعة من كائنات Method ، ويمثل كل Method طريقة الطريقة المعلنة في فئة ما. للحصول على الطريقة المحددة ، يمكنك استدعاء getDeclaredMethod(String name, Class...<T> parameterTypes) .
كما هو موضح في الكود التالي:
private static void showdeclaredmethods () {student student = new student ("Bill" ، 18) ؛ // احصل على جميع الأساليب المعلنة بواسطة طريقة فئة الطالب [] الأساليب = student.getClass (). getDeclaredMethods () ؛ جرب {// الحصول على كائن SearnMethod (مغلف طريقة التعلم) method methodmethod = student.getClass (). getDeclaredMethod ("Learn" ، string.class) ؛ // احصل على قائمة المعلمات لطريقة التعلم وطباعتها من فئة <؟> [] paramClasses = LearnMethod.getParameterTypes () ؛ for (class <؟> class: paramclasses) {system.out.println ("Learn Method Parameters:" + class.getName ()) ؛ }. // استدعاء طريقة تعلم LearnMethod.invoke (الطالب ، "انعكاس Java") ؛ } catch (استثناء e) {}} احصل على أساليب عامة معلنة في الفصل الحالي وفئة الوالدين
للحصول على الفئة الحالية وجميع الأساليب public المعلنة في الفئة الأصل ، يمكنك استدعاء وظيفة getMethods ، وللحصول على طريقة public محددة ، يمكنك استدعاء طريقة getMethod . يرجى الاطلاع على الرمز التالي:
private static void showmethods () {student student = new student ("Mr.Simple") ؛ // احصل على جميع الأساليب العامة (بما في ذلك الطالب نفسه ومرورًا من طريقة فئة الأصل) [] الأساليب = student.getClass (). getMethods () ؛ جرب {// لاحظ أنه يمكن الحصول على الأساليب العامة فقط من خلال getMethod. إذا حاولت الحصول على طريقة خاصة ، فسيتم طرح استثناء. طريقة learnmethod = student.getClass (). getMethod ("تعلم" ، string.class) ؛ } catch (استثناء e) {}} احصل على السمات المحددة في الفصل عن طريق التأمل
يشبه الحصول على السمات الحصول على أساليب ، باستثناء أن أساليب getMethods() / getDeclaredMethods() يتم استبدالها بمكالمة إلى أساليب getFields() / getDeclaredFields() .
احصل على السمات المحددة في الفئة الحالية (باستثناء السمات الموروثة من الفئة الأصل)
للحصول على جميع السمات المحددة في الفئة الحالية (بما في ذلك السمات المختلفة مثل private ، public ، static ، وما إلى ذلك) ، يمكنك استدعاء وظيفة getDeclaredFields لكائن الفئة ؛ للحصول على السمات المحددة ، يمكنك استدعاء getDeclaredField .
كما هو موضح في الكود التالي:
private static void showdeclaredfields () {student student = new student ("Bill" ، 18) ؛ // الحصول على جميع السمات المحددة في حقل الفئة الحالي [] الحقول = student.getClass (). getDeclaredFields () ؛ حاول {// الحصول على السمة المحددة حقل dgrayField = student.getClass (). getDeclaredField ("Grade") ؛ // احصل على قيمة السمة system.out.println ("الدرجة هي:" + dgentfield.getint (student)) ؛ // قم بتعيين قيمة السمة drentfield.set (الطالب ، 10) ؛ } catch (استثناء e) {}} احصل على السمات العامة المحددة في الفئة الحالية والفئة الأم
للحصول على جميع الخصائص public المحددة في الفئة الحالية والفئة الأصل ، يمكنك استدعاء وظيفة getFields لكائن Class . للحصول على خاصية public محددة ، يمكنك الاتصال بطريقة getField ، كما هو موضح في الكود التالي:
Private Static Void Showfields () {student student = new student ("Bill" ، 18) ؛ // احصل على جميع الخصائص العامة لحقل الفئة والوالدين الحالية [] PublicFields = student.getClass (). getFields () ؛ } انعكاس للحصول على فئة الأصل للفئة والواجهة التي تنفذها الفصل
احصل على فئة الوالدين
ما عليك سوى استدعاء طريقة getSuperClass لكائن Class ، كما هو موضح في الكود التالي:
الطالب الطالب = طالب جديد ("بيل" ، 18) ؛ الفصل <؟> فائق الفائق = student.getClass (). getSuperClass () ؛ احصل على الواجهة المنفذة
لمعرفة أي مفاتيح تنفذ الفئة ، ما عليك سوى استدعاء طريقة getInterfaces لكائن Class ، كما هو موضح في الكود التالي:
private static void showinterfaces () {student student = new student ("Bill" ، 19) ؛ الفصل <؟> [] واجهات = student.getClass (). getInterfaces () ؛}لخص
ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يكون ذلك مفيدًا لدراسة الجميع والعمل.