1. ما هي آلية الانعكاس؟
ببساطة، تعني آلية الانعكاس أن البرنامج يمكنه الحصول على معلوماته الخاصة أثناء تشغيله. في Java، طالما تم تقديم اسم الفصل، يمكن الحصول على جميع المعلومات حول الفصل من خلال آلية الانعكاس.
2. أين يتم استخدام آلية الانعكاس؟
في بعض الأحيان، استخدمنا بعض المعرفة، لكننا لا نعرف ما هي المصطلحات المهنية. عندما تعلمنا للتو jdbc، استخدمنا سطرًا من التعليمات البرمجية، Class.forName("com.mysql.jdbc.Driver.class"). newInstance() ؛ ولكن في ذلك الوقت، كنت أعرف فقط أن هذا السطر من التعليمات البرمجية قد أنشأ مثيل كائن برنامج التشغيل، ولم أكن أعرف معناه المحدد. بعد الاستماع إلى الدرس الخاص بآلية الانعكاس، أدركت أن هذا هو الانعكاس. في الوقت الحاضر، تستخدم العديد من الأطر المفتوحة آلية الانعكاس.
3. مزايا وعيوب آلية الانعكاس
لماذا نستخدم آلية الانعكاس؟ ألا يكفي إنشاء الكائنات مباشرة؟ وهذا يشمل مفاهيم ديناميكية وثابتة.
التجميع الثابت: يتم تحديد النوع في وقت الترجمة ويتم ربط الكائن، أي يتم تمريره.
التجميع الديناميكي: تحديد النوع وربط الكائن في وقت التشغيل. يعمل التجميع الديناميكي على زيادة مرونة Java إلى الحد الأقصى، ويجسد التطبيقات متعددة الأشكال، ويقلل من الاقتران بين الفئات.
باختصار، تتمثل ميزة آلية الانعكاس في قدرتها على إنشاء الكائنات وتجميعها ديناميكيًا، مما يُظهر مرونة كبيرة خاصة في تطوير J2EE، حيث تكون مرونتها واضحة جدًا. على سبيل المثال، بالنسبة لبرنامج واسع النطاق، من المستحيل تصميمه بشكل مثالي دفعة واحدة. بعد تجميع البرنامج وإصداره، عندما يتبين أن بعض الوظائف تحتاج إلى التحديث، لا يمكننا أن نطلب من المستخدم إلغاء تثبيت الوظيفة السابقة. واحد ثم أعد تثبيته الإصدار الجديد، إذا كان هذا هو الحال، فمن المؤكد أن العديد من الأشخاص لن يستخدموا هذا البرنامج. إذا كان ثابتًا، فيجب إعادة ترجمة البرنامج بأكمله مرة واحدة لتحقيق تحديث الوظيفة. وإذا كان يستخدم آلية الانعكاس، فلا يلزم إلغاء تثبيته، بل يحتاج فقط إلى إنشائه وتجميعه ديناميكيًا في وقت التشغيل لتحقيق الوظيفة.
عيبه هو تأثيره على الأداء. يعد استخدام الانعكاس في الأساس عملية مفسرة حيث يمكننا إخبار JVM بما نريد القيام به ويلبي متطلباتنا. تكون مثل هذه العمليات دائمًا أبطأ من مجرد إجراء نفس العملية مباشرةً.
4. ما هي المعلومات التي يمكن الحصول عليها باستخدام آلية الانعكاس؟
باختصار، يمكنه الحصول على أي معلومات موجودة في الفصل، ولكن الشرط الأساسي هو معرفة اسم الفصل، وإلا فلن تكون هناك معلومات إضافية. أولاً، يجب إنشاء كائن الفصل بناءً على الاسم الكامل للفئة الطبقة الواردة.
Class c=Class.forName("className"); ملاحظة: يجب أن يكون اسم الفئة هو الاسم الكامل، أي أنه يجب أن يتضمن اسم الحزمة، على سبيل المثال، cn.netjava.pojo.UserInfo;
Object obj=c.newInstance();// أنشئ مثيلًا للكائن
حسنًا، بمجرد حصولك على شيء ما، يصبح من السهل التعامل مع كل شيء، ويمكنك الحصول على أي معلومات تريدها.
كيفية الحصول على المنشئ
المُنشئ getConstructor(Class[] params)// احصل على المُنشئ العام وفقًا للمعلمات المحددة
Constructor[] getConstructors()// احصل على جميع المُنشئين العامين
المُنشئ getDeclaredConstructor(Class[] params)// احصل على المنشئات العامة وغير العامة بناءً على المعلمات المحددة
Constructor[] getDeclaredConstructors()// احصل على جميع المُنشئين العامين
الحصول على طريقة طريقة الفصل
طريقة getMethod (اسم السلسلة، معلمات الفئة [])، احصل على الطريقة بناءً على اسم الطريقة ونوع المعلمة
Method[] getMethods()// احصل على جميع الطرق العامة
الطريقة getDeclaredMethod(String name, Class[] params)// وفقًا لاسم الطريقة ونوع المعلمة، احصل على الطرق العامة وغير العامة
Method[] getDeclaredMethods()// احصل على جميع الطرق العامة وغير العامة
كيفية الحصول على السمات في الفصل
الحقل getField(String name)// احصل على المتغير العام المقابل وفقًا لاسم المتغير
Field[] getFields()// احصل على جميع الطرق العامة في الفصل
الحقل getDeclaredField(اسم السلسلة)//احصل على المتغيرات العامة وغير العامة بناءً على اسم الطريقة
Field[] getDeclaredFields()// احصل على جميع الأساليب العامة وغير العامة في الفصل
هذه هي الأشياء الشائعة الاستخدام، إذا كنت تعرفها، فسيكون من السهل التعامل مع كل شيء آخر...
5. ما الذي يمكن عمله بآلية الانعكاس؟
عندما بدأت استخدام jdbc لأول مرة، شعرت بالرغبة في القيء عندما كتبت للوصول إلى قاعدة البيانات، وكان هناك ثمانية جداول، وكان كل جدول يحتوي على عمليات إضافة وحذف وتعديل وبحث آلية الانعكاس، لذلك كتبت عن إنشاء فئات DAO مختلفة في الجدول، والتي لا تؤدي إلى تسريع عملية التطوير فحسب، بل تجعل الكود أيضًا زائدًا عن الحاجة، والأمر الأكثر فظاعة هو أنها تبدو متشابهة تقريبًا، ثم تقوم بنسخها وتعديلها مباشرة. لأنه من السهل ارتكاب العديد من الأخطاء ذات المستوى المنخفض (الأحرف الكبيرة والصغيرة، أو حرف واحد إضافي أو حرف واحد مفقود...)، وقد يستغرق خطأ واحد وقتًا طويلاً للعثور عليه.
باستخدام آلية انعكاس Java، من السهل التعامل مع كل شيء، ما عليك سوى كتابة فئة داو بأربعة طرق، وإضافة كائنات مختلفة وحذفها وتعديلها والاستعلام عنها وتمريرها dao لكل جدول، ستقوم آلية الانعكاس بالباقي تلقائيًا، وهذا هو مصلحتها. بصراحة، تم تصميم آلية الانعكاس لمساعدتنا في القيام بأشياء متكررة ومنتظمة، لذا فإن العديد من البرامج التي تولد التعليمات البرمجية تلقائيًا تستخدم الآن آلية الانعكاس لإكمالها طالما قمت بإدخال المعلمات ذات الصلة وفقًا للقواعد. مبرمجو المستوى بطيئون تم طمس البطيئين، لماذا؟ لأنه ليست هناك حاجة لكتابة التعليمات البرمجية، يمكن لأي شخص تطويرها، فلماذا يفعل المبرمجون ذلك؟ لذلك لدينا طريقة واحدة فقط للخروج، وهي العمل الجاد والعمل الجاد، وأن نصبح مبرمجين كبارًا، ونتخصص في تطوير البرامج الغبية، وندع المبرمجين الآخرين يتنحون جانبًا ويهدأون، هاها~
6. مثال على استخدام آلية الانعكاس لإضافة وتدقيق بيانات قاعدة البيانات
المبدأ الأساسي: عند حفظ البيانات، قم بإزالة جميع قيم السمات للكائنات التي تحتاج إلى حفظها، ثم قم بتجميع عبارة SQL للاستعلام، وحزم جميع البيانات التي تم الاستعلام عنها في كائن جافا.
قواعد اللعبة: كما يقول المثل، لا يوجد شيء بدون قواعد، خاصة بالنسبة للبرامج، فهي لا تستطيع فعل الأشياء بدون قواعد.
1) يحتوي كل كائن جدول في قاعدة البيانات على فئة pojo، وكل حقل في الجدول يتوافق مع سمة في فئة pojo. علاوة على ذلك، فإن اسم فئة pojo هو نفس اسم الجدول، واسم السمة واسم الحقل متماثلان. لا يهم حالة الأحرف، لأن قاعدة البيانات ليست حساسة لحالة الأحرف بشكل عام.
2) أضف مجموعة قياسية واحصل على طرق لكل سمة في فئة pojo.
مع قواعد اللعبة، دعونا نبدأ اللعب.
1. أولاً، يوجد جدول في قاعدة البيانات. افترض أن اسم قاعدة البيانات هو: blogsystem، واسم الجدول فيها هو userinfo. كما هو موضح في الصورة:
2. قم بإنشاء فئة pojo المقابلة:
انسخ رمز الكود كما يلي:
الحزمة cn.netjava.pojo;
معلومات المستخدم للفئة العامة {
معرف int الخاص؛
اسم سلسلة خاصة؛
سلسلة خاصة الأشخاص ذوي الإعاقة؛
عمر خاص؛
@تجاوز
سلسلة عامة إلى سلسلة () {
إرجاع "معلومات المستخدم [id = " + id + "، name = " + name + "، pwd = " + pwd + "، age = "
+ العمر + "]";
}
public int getId() {
معرف العودة؛
}
مجموعة الفراغ العام (معرف كثافة العمليات) {
this.id = id;
}
سلسلة عامة getName () {
اسم الإرجاع؛
}
اسم مجموعة الفراغ العام (اسم السلسلة) {
this.name = name;
}
سلسلة عامة getPwd () {
عودة الأشخاص ذوي الإعاقة؛
}
مجموعة الفراغ العام (سلسلة pwd) {
this.pwd = pwd;
}
كثافة العمليات العامة getAge() {
سن العودة؛
}
مجموعة الفراغ العام (int age) {
this.age = age;
}
}
2. اكتب فئة المصنع للحصول على اتصال قاعدة البيانات:
انسخ رمز الكود كما يلي:
الحزمة cn.netjava.factory;
استيراد java.sql.Connection؛
استيراد java.sql.DriverManager؛
الطبقة العامة Connect2DBFactory {
اتصال ثابت عام getDBConnection() {
اتصال كون = فارغ؛
يحاول {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/blogsystem";
مستخدم السلسلة = "الجذر"؛
كلمة مرور السلسلة = "netjava"؛
conn = DriverManager.getConnection(url, user,password);
} قبض (الاستثناء ه) {
printStackTrace();
}
العودة كون؛
}
}
3. تبدأ المتعة بكتابة فئة الداو التي تقوم بتشغيل قاعدة البيانات
انسخ رمز الكود كما يلي:
الحزمة cn.netjava.session؛
import java.lang.reflect.Field;
import java.lang.reflect.Method;
استيراد java.sql.Connection؛
import java.sql.PreparedStatement;
import java.sql.ResultSet;
استيراد java.sql.SQLException؛
استيراد java.sql.Statement؛
import java.util.ArrayList;
import java.util.List;
import cn.netjava.factory.Connect2DBFactory;
import cn.netjava.pojo.UserInfo;
الطبقة العامة NetJavaSession {
/**
* تحليل عبارة SQL التي تحفظ الكائن
*
*كائنparam
*: الكائن الذي يحتاج إلى الحفظ
* @return: عبارة SQL لحفظ الكائن
*/
سلسلة ثابتة عامة getSaveObjectSql(كائن كائن) {
// تحديد سلسلة SQL
سلسلة SQL = "أدخل في"؛
// احصل على فئة الكائن
الفئة ج = object.getClass();
// احصل على كافة الأساليب الموجودة في الكائن
الطريقة[] الطرق = c.getMethods();
// احصل على كافة الخصائص الموجودة في الكائن
الحقل[] الحقول = c.getFields();
// احصل على اسم فئة الكائن
String cName = c.getName();
// تحليل اسم الجدول من اسم الفئة
String tableName = cName.substring(cName.lastIndexOf(".") + 1،
cName. length());
sql += tableName + "(";
List<String> mList = new ArrayList<String>();
List vList = new ArrayList();
لـ (طريقة الطريقة: الطرق) {
String mName =method.getName();
إذا (mName.startsWith("get") && !mName.startsWith("getClass")) {
String fieldName = mName.substring(3, mName. length());
mList.add(fieldName);
System.out.println("اسم الحقل----->" + fieldName);
يحاول {
قيمة الكائن = الطريقة.invoc(object, null);
System.out.println("القيمة التي يتم إرجاعها بواسطة طريقة التنفيذ:" + value);
إذا (قيمة مثيل السلسلة) {
vList.add("/"" + value + "/"");
System.out.println("قيمة الحقل------>" + value);
} آخر {
vList.add(value);
}
} قبض (الاستثناء ه) {
printStackTrace();
}
}
}
لـ (int i = 0; i < mList.size(); i++) {
إذا (i < mList.size() - 1) {
sql += mList.get(i) + "؛"
} آخر {
sql += mList.get(i) + ")values(";
}
}
for (int i = 0; i < vList.size(); i++) {
إذا (i < vList.size() - 1) {
sql += vList.get(i) + "؛"
} آخر {
sql += vList.get(i) + ")";
}
}
إرجاع SQL؛
}
القائمة العامة الثابتة getDatasFromDB(String tableName, int Id) {
عودة فارغة؛
}
/**
* حفظ الكائن في قاعدة البيانات
*
*كائنparam
*: الكائن الذي يحتاج إلى الحفظ
* @return: نتيجة تنفيذ الطريقة 1: تشير إلى النجاح، 0: تشير إلى الفشل
*/
عامة int saveObject(كائن كائن) {
Connection con = Connect2DBFactory.getDBConnection();
String sql = getSaveObjectSql(object);
يحاول {
// بيان البيان=(Statement) con.createStatement();
PreparedStatement psmt = con.prepareStatement(sql);
psmt.executeUpdate();
العودة 1؛
} قبض على (SQLException ه) {
printStackTrace();
العودة 0؛
}
}
/**
* الحصول على الكائن من قاعدة البيانات
*
* @param arg0
*: الفئة التي ينتمي إليها الكائن
* @معرف المعلمة
*: معرف الكائن
*return: الكائن المراد العثور عليه
*/
الكائن العام getObject(String className, int Id) {
// احصل على اسم الجدول
String tableName = className.substring(className.lastIndexOf(".") + 1,
className. length());
// إنشاء كائن فئة بناءً على اسم الفئة
الفئة ج = فارغة؛
يحاول {
ج = Class.forName(className);
} التقاط (ClassNotFoundException e1) {
e1.printStackTrace();
}
// قم بتجميع بيان SQL للاستعلام
String sql = "select * from " + tableName + " Where Id = " + Id؛
System.out.println("ابحث عن عبارة SQL:" + sql);
// احصل على رابط قاعدة البيانات
Connection con = Connect2DBFactory.getDBConnection();
// أنشئ مثيلًا للفئة
Object obj = null;
يحاول {
البيان stm = con.createStatement();
// احصل على مجموعة النتائج التي تم إرجاعها عن طريق تنفيذ عبارة البحث
ResultSet set = stm.executeQuery(sql);
// احصل على مصفوفة أسلوب الكائن
الطريقة[] الطرق = c.getMethods();
// اجتياز مجموعة النتائج
بينما (set.next()) {
obj = c.newInstance();
// طرق اجتياز الكائنات
لـ (طريقة الطريقة: الطرق) {
StringmethodName =method.getName();
// إذا كانت طريقة الكائن تبدأ بـ set
إذا (methodName.startsWith("set")) {
// احصل على اسم الحقل في جدول البيانات بناءً على اسم الطريقة
String columnName =methodName.substring(3,
methodName.length());
// احصل على نوع معلمة الطريقة
Class[] parmts =method.getParameterTypes();
إذا (parmts[0] == String.class) {
// إذا كانت المعلمة من نوع السلسلة، فاحصل على القيمة المقابلة من مجموعة النتائج وفقًا لاسم العمود، وقم بتنفيذ طريقة المجموعة
way.invoc(obj, set.getString(columnName));
}
إذا (parmts[0] == int.class) {
way.invoc(obj, set.getInt(columnName));
}
}
}
}
} قبض (الاستثناء ه) {
printStackTrace();
}
كائن الإرجاع؛
}
}
4. ماذا عن تأثير بدء الاختبار:
انسخ رمز الكود كما يلي:
الحزمة cn.netjava.tester؛
import cn.netjava.pojo.UserInfo;
import cn.netjava.session.NetJavaSession;
اختبار الطبقة العامة {
public static void main(String args[]) {
// احصل على كائن NetJavaSession
جلسة NetJavaSession = new NetJavaSession();
// إنشاء كائن معلومات المستخدم
UserInfo user = new UserInfo();
// قم بتعيين خصائص الكائن
user.setId(6988);
user.setAge(44);
user.setPwd("pwd");
user.setName("champion");
// احفظ الكائن في قاعدة البيانات
String sql = session.getSaveObjectSql(user);
System.out.println("بيان SQL لحفظ الكائن:" + sql);
// ابحث عن كائن
معلومات المستخدم userInfo = (معلومات المستخدم) session.getObject(
"cn.netjava.pojo.UserInfo"، 6988)؛
System.out.println("المعلومات التي تم الحصول عليها:" + userInfo);
}
}
5. النتائج المطبوعة:
7. دعونا نلخص
بشكل عام، تعد آلية الانعكاس في Java مفيدة للغاية، حيث يمكنها حل العديد من الأشياء الميتة، لأن آلية الانعكاس مرنة للغاية، ولا نحتاج إلى قضاء الكثير من الوقت في كتابة العمليات بدلاً من استخدام كود قاعدة البيانات. تقضي الطريقة وقتًا أطول في الوظائف المنطقية للمشروع، وهذا يمكن أن يقلل بشكل كبير من وقت التطوير ويجعل الكود أكثر قابلية للقراءة. تستخدم العديد من أطر العمل مفتوحة المصدر الحالية آليات الانعكاس، فهي تحتاج فقط إلى تكوين الملفات ثم استدعاء أساليبها وفقًا للقواعد.