تستخدم العديد من الأطر السائدة تقنية الانعكاس، على سبيل المثال، يستخدم إطار عمل ssh تقنيتين: XML كملف تكوين + تقنية الانعكاس.
الحزم الصفية المتعلقة بالتفكير.
java.lang.reflect.*;
جميع الأنواع في Java (بما في ذلك الأنواع الأساسية) تتوافق مع كائن Class، وهذه الفئة هي java.lang.Class. أي أن كل نوع يحتوي على كائن فئة مطابق له في فئة لا يحتوي على مُنشئ عام. لاحظ أنه لا يوجد وصول عام.
كيفية الحصول على كائن فئة
انسخ رمز الكود كما يلي:
.لكل object.getCalss()، يمكنك الحصول على الفئة المقابلة.
.Class.forName(String)، طريقة كتابة السلسلة: اسم الحزمة.اسم الفئة. سيتم إنشاء الكائن المطابق لاسم الحزمة.ملاحظة: 1.2 ينطبق فقط على أنواع المراجع.
.بالنسبة للأنواع الأساسية: تمثل فئة التغليف TYPE كائن الفئة من النوع الأساسي المقابل. ويتوافق TYPE مع كائن الفئة int. ملاحظة: 3 ينطبق فقط على الأنواع الأساسية.
.النوع، الفئة. <النوع 4 عالمي.>
من بين الطرق الأربع المذكورة أعلاه، الطريقة الثانية فقط هي الطريقة الديناميكية. فقط قم بتغيير الحزمة التي لديها إمكانات ديناميكية.
يوجد كائن فئة واحد فقط من كل نوع، أي أن لديهم عنوانًا واحدًا فقط، ولكن الأنواع المختلفة مختلفة.
وبالتالي فإن نتائج الطباعة التالية كلها صحيحة.
انسخ رمز الكود كما يلي:
// أنواع الأزواج والمراجع
Class c1 = "".getClass();
Class c2 = Class.forName("java.lang.String");
فئة c3 = String.class;
System.out.println(c1 ==c2);//true
// للأنواع الأساسية
فئة num1 = Integer.TYPE؛
فئة num2 = int.class;
System.out.println(num1 == num2);//true
التفكير للحصول على الأساليب ذات الصلة للأعضاء في الفصل
[احصل على البنية <وفقًا لنوع المعلمة>] (يستخدم بشكل عام دون التصريح عنها)
انسخ رمز الكود كما يلي:
منشئ<T> getConstructor(Class<?>...parameterTypes)
تقوم بإرجاع كائن منشئ يعكس المُنشئ العام المحدد للفئة التي يمثلها كائن الفئة هذا.
المُنشئ<?>[] getConstructors()
تقوم بإرجاع مصفوفة تحتوي على كائنات Constructor التي تعكس كافة المنشئات العامة للفئة التي يمثلها كائن Class هذا.
منشئ<T> getDeclardConstructor(Class<?>...parameterTypes)
تقوم بإرجاع كائن مُنشئ يعكس طريقة المُنشئ المحددة للفئة أو الواجهة التي يمثلها كائن الفئة هذا.
المُنشئ<?>[] getDeclaredConstructors()
تقوم بإرجاع مصفوفة من كائنات المُنشئ التي تعكس جميع أساليب المُنشئ المعلنة بواسطة الفئة التي يمثلها كائن الفئة هذا.
[الحصول على السمة <وفقًا لاسم السمة>] (يُستخدم عادةً مع المُعلن، لأن السمات تكون خاصة بشكل عام)
انسخ رمز الكود كما يلي:
حقل getField (اسم السلسلة)
تقوم بإرجاع كائن حقل يعكس حقول الأعضاء العامة المحددة للفئة أو الواجهة التي يمثلها كائن الفئة هذا.
الحقل [] الحصول على الحقول ()
تقوم بإرجاع مصفوفة تحتوي على كائنات الحقل التي تعكس جميع الحقول العامة التي يمكن الوصول إليها للفئة أو الواجهة التي يمثلها كائن الفئة هذا.
الحقل getDeclaredField (اسم السلسلة)
تقوم بإرجاع كائن الحقل الذي يعكس الحقل المعلن المحدد للفئة أو الواجهة التي يمثلها كائن الفئة هذا.
الحقل [] الحصول على الحقول المحددة ()
تقوم بإرجاع مصفوفة من كائنات الحقل التي تعكس جميع الحقول المعلنة بواسطة الفئة أو الواجهة التي يمثلها كائن الفئة هذا.
[الحصول على الطريقة <اسم الطريقة بالإضافة إلى نوع المعلمة>] (يُستخدم عادةً بدون التصريح عنها)
انسخ رمز الكود كما يلي:
طريقة getMethod (اسم السلسلة، الفئة <؟>... أنواع المعلمات)
تقوم بإرجاع كائن أسلوب يعكس أسلوب العضو العام المحدد للفئة أو الواجهة التي يمثلها كائن الفئة هذا.
الطريقة [] الحصول على الأساليب ()
تقوم بإرجاع مصفوفة تحتوي على كائنات الطريقة التي تعكس الأعضاء العامين للفئة أو الواجهة التي يمثلها كائن الفئة هذا (بما في ذلك تلك التي تم الإعلان عنها بواسطة تلك الفئة أو الواجهة وتلك الموروثة من طريقة الفئات الفائقة والواجهات الفائقة).
الطريقة getDeclaredMethod(String name, Class<?>...parameterTypes)
تقوم بإرجاع كائن أسلوب يعكس الطريقة المعلنة المحددة للفئة أو الواجهة التي يمثلها كائن الفئة هذا.
الطريقة[] getDeclaredMethods()
تقوم بإرجاع مصفوفة من كائنات الطريقة التي تعكس جميع الأساليب المعلنة بواسطة الفئة أو الواجهة التي يمثلها كائن الفئة هذا، بما في ذلك الوصول العام والمحمي والافتراضي (الحزمة) والطرق الخاصة، ولكن باستثناء الطرق الموروثة.
T newInstance()
إنشاء مثيل جديد للفئة التي يمثلها كائن الفئة هذا. <يمكن للمثيل الجديد () إنشاء الكائنات ديناميكيًا>
سلسلة إلى سلسلة ()
تحويل الكائن إلى سلسلة.
يلاحظ: يستدعي newInstance() مُنشئًا بدون معلمات. إذا لم يكن لدى الفئة مُنشئ بدون معلمات، فسيقوم newInstance() بإنشاء استثناء.
الأساليب المعلنة تدعم الخصوصية، ولكنها لا تدعم الميراث. الأساليب غير المعلنة تدعم الميراث، ولكنها لا تدعم الخصوصية، ويمكنها فقط إزالة الأشياء العامة.
لذلك، يتم الإعلان عن الخصائص بشكل عام مع الإعلان، لأن الخصائص بشكل عام خاصة، ويتم الحصول على الأساليب بشكل عام بدون إعلان، ويتم الحصول على المنشئات بشكل عام بدون إعلان.
يحصل انعكاس محاكاة المثيل على الخصائص والأساليب ذات الصلة في الفصل
استخدام الانعكاس لتعيين قيم للخصائص
الأساليب في الميدان
الحصول على الكائن (كائن الكائن)
إرجاع قيمة الحقل الذي يمثله هذا الحقل على الكائن المحدد.
الحقل f = c.getXXField(اسم الخاصية);
القيمة = f.get(object);
مجموعة باطلة (كائن كائن، قيمة الكائن)
يقوم بتعيين الحقل الذي يمثله كائن الحقل هذا في متغير الكائن المحدد إلى القيمة الجديدة المحددة.
f.set(object, value);
فئة<?> getType()
تقوم بإرجاع كائن فئة يحدد النوع المعلن للحقل الذي يمثله كائن الحقل هذا.
يستخدم للحصول على نوع السمة (إرجاع كائن الفئة).
انسخ رمز الكود كما يلي:
الفئة ج = Student.class؛
Object obj = c.newInstance(); // إنشاء كائن من فئة الطالب
Field f = c.getDeclaredField("name"); // احصل على سمة الاسم
f.setAccessible(true); //تعيين الوصول الخاص.
f.set(obj, "zhangsan");
System.out.println(f.get(obj)); // احصل على قيمة سمة اسم الكائن.
استخدام الانعكاس لاستدعاء البنيات يتم الاستدعاء الفعلي للمنشئ عند استدعاء الأسلوب newInstance().
انسخ رمز الكود كما يلي:
Class c = Class.forName("com.clazz.reflect.Student");
Constructor con = c.getConstructor(); // لم يتم تنفيذ البناء،
Object cObj = c.getConstructor().newInstance();// اتصل بالمنشئ بدون معلمات
Constructor conAll = c.getConstructor(int.class,String.class,int.class);
Object caobj = conAll.newInstance(1001,"zjamgs",234235);// اتصل بالمنشئ باستخدام المعلمات.
System.out.println(caobj); //طباعة الإخراج
طرق الدعوة باستخدام الانعكاس اسم الكائن. الطريقة (القيمة 1،2،3)؛
الطريقة m = c.getMethoed(اسم الطريقة، نوع المعلمة...);
m.invoc (كائن، معلمات استدعاء الطريقة) إذا كانت المعلمة الرسمية المطلوبة بواسطة الطريقة الأساسية هي 0، فيمكن أن يكون طول مصفوفة الوسائط المتوفرة 0 أو فارغة.
انسخ رمز الكود كما يلي:
Class c = Class.forName("com.clazz.reflect.Student");
Object obj = c.newInstance(); // إنشاء كائن Sutdent.
الطريقة msetName = c.getMethod("setName"، String.class)؛//obj لا يحتاج إلى تحويل النوع
msetName.invoc(obj, "zhangsan");// طريقة الاتصال setName وتمرير المعلمات.
الطريقة msetId = c.getMethod("setId"، int.class);
msetId.invoc(obj, 409090202);
System.out.println(obj);
أمثلة على تطبيق الانعكاس فئة الكيان
انسخ رمز الكود كما يلي:
package org.dennisit.reflect.entity;
استيراد java.io.Serializable؛
/**
*
* المستخدم جافا
*
* @الإصدار: 1.1
*
*@author: Su Ruonian<a href="mailto:
[email protected]">أرسل بريدًا إلكترونيًا</a>
*
*@منذ: 1.0 وقت الإنشاء: 2013-2-26 01:43:56 مساءً
*
* TODO: يتم استخدام فئة User.java لـ ...
*
*/
يقوم مستخدم الفئة العامة بتنفيذ Serializable{
اختبار سلسلة خاصة؛
تنفيذ الفراغ العام (اسم السلسلة، عمر int) {
System.out.println("name=" + name + ",age=" + age);
}
}
فئة اختبار الانعكاس
انسخ رمز الكود كما يلي:
الحزمة org.dennisit.reflect.main;
import java.lang.reflect.Field;
/**
*
* ReflectEx.java
*
* @الإصدار: 1.1
*
*@author: Su Ruonian<a href="mailto:
[email protected]">أرسل بريدًا إلكترونيًا</a>
*
*@منذ: 1.0 وقت الإنشاء: 2013-2-26 01:46:00 مساءً
*
* TODO: يتم استخدام فئة ReflectEx.java لـ ...
*
*/
الطبقة العامة ReflectEx {
public static void main(String[] args)throws Exception {
Class cls = Class.forName("org.dennisit.reflect.entity.User");
Object obj = cls.newInstance(); // إنشاء كائن مستخدم
الحقل f = cls.getDeclaredField("test"); // احصل على سمة الاختبار
f.setAccessible(true); // فتح أذونات الوصول لاختبار السمات الخاصة
f.set(obj, "zhangsan"); // انسخ مرة أخرى للاختبار
System.out.println(f.get(obj)); // احصل على قيمة سمة الاختبار لـ obj
// احصل على الطريقة بناءً على اسم الطريقة المنفذة
java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class);
m.invoc(obj, "dennisit",23); // طريقة تنفيذ المكالمة
}
}
تأثير العملية
انسخ رمز الكود كما يلي:
com.zhangsan
الاسم = دينيسيت، العمر = 23
مثال على كتابة فئة إنشاء مثيل ديناميكي عاكس
انسخ رمز الكود كما يلي:
الحزمة org.dennisit.reflect.main;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
/**
*
* DynamicReflect.java
*
* @الإصدار: 1.1
*
*@author: Su Ruonian<a href="mailto:
[email protected]">أرسل بريدًا إلكترونيًا</a>
*
*@منذ: 1.0 وقت الإنشاء: 2013-2-26 01:58:12 مساءً
*
* TODO: مثال على الإنشاء الديناميكي باستخدام الانعكاس
*
*/
الطبقة العامة DynamicReflect {
الكائن الثابت العام getInstance(String className,Map<String,Object> Map)throws Exception{
Class c = Class.forName(className);
Object obj = c.newInstance(); // كائن كائن
Set<String>keys = Map.keySet(); // احصل على جميع السمات المقابلة
Field[] fAll = c.getDeclaredFields(); // احصل على جميع الخصائص في الفصل
for(int i=0;i<fAll.length;i++){
for(String key:keys){ // مطابقة الحلقة
if(fAll[i].getName().equals(key)){ // إذا كانت السمة التي مررها المستخدم تتطابق مع اسم السمة في الفئة التي تم الحصول عليها
الحقل f = c.getDeclaredField(key);//احصل على هذه السمة
// أنشئ اسم طريقة setXxx ().
String MethodName = "set" + key.substring(0,1).toUpperCase()+key.substring(1);
طريقة الطريقة = c.getMethod(methodName, f.getType());// احصل على الطريقة المقابلة بناءً على اسم المستخدم الذي تم إنشاؤه
Method.invoc(obj, Map.get(key));//استدعاء الطريقة
}آخر{
يكمل؛
}
}
}
كائن الإرجاع؛
}
}
بعد ذلك، نختبر مثال إنشاء الانعكاس الديناميكي الذي كتبناه
فئة الكيان
انسخ رمز الكود كما يلي:
package org.dennisit.reflect.entity;
استيراد java.io.Serializable؛
/**
*
* المستخدم جافا
*
* @الإصدار: 1.1
*
*@author: Su Ruonian<a href="mailto:
[email protected]">أرسل بريدًا إلكترونيًا</a>
*
*@منذ: 1.0 وقت الإنشاء: 2013-2-26 01:43:56 مساءً
*
* TODO: فئة الكيان
*
*/
يقوم مستخدم الفئة العامة بتنفيذ Serializable{
اسم سلسلة خاصة؛
عمر خاص؛
البريد الإلكتروني الخاص بالسلسلة؛
public User() { // يجب ألا يحتوي على مُنشئ معلمات
}
// getter() و setter()
}
فئة الاختبار الرئيسية
انسخ رمز الكود كما يلي:
الحزمة org.dennisit.reflect.main;
import java.util.HashMap;
import java.util.Map;
import org.dennisit.reflect.entity.User;
/**
*
* ReflectEx.java
*
* @الإصدار: 1.1
*
*@author: Su Ruonian<a href="mailto:
[email protected]">أرسل بريدًا إلكترونيًا</a>
*
*@منذ: 1.0 وقت الإنشاء: 2013-2-26 01:46:00 مساءً
*
* TODO: يتم استخدام فئة ReflectEx.java لـ ...
*
*/
الطبقة العامة ReflectEx {
public static void main(String[] args)throws Exception {
Class cls = Class.forName("org.dennisit.reflect.entity.User");
String className = "org.dennisit.reflect.entity.User";
Map<String,Object> Map = new HashMap<String, Object>();
Map.put("name", "dennisit");
Map.put("age", 22);
Map.put("email", "[email protected]");
User user = (User)DynamicReflect.getInstance(className,map);
System.out.println(user.getName() + ""، + user.getAge() + ""، + user.getEmail());
}
}
نتائج تشغيل البرنامج
انسخ رمز الكود كما يلي: