لفهم مبدأ التفكير ، يجب أولاً أن تفهم نوع المعلومات. تسمح لنا Java بتحديد معلومات الكائنات والفئات في وقت التشغيل ، وهناك طريقتان رئيسيتان: أحدهما هو RTTI التقليدي ، الذي يفترض أننا نعرف بالفعل جميع المعلومات في وقت الترجمة ؛ والآخر هو آلية الانعكاس ، والتي تسمح لنا باكتشاف واستخدام معلومات الفئات في وقت التشغيل .
1. كائن فئة
لفهم كيفية عمل RTTI في Java ، تحتاج أولاً إلى معرفة كيفية تمثيل معلومات النوع في وقت التشغيل. يتم ذلك بواسطة كائنات الفصل ، والتي تحتوي على معلومات متعلقة بالفصول. يتم استخدام كائنات الفئة لإنشاء جميع الكائنات "العادية". تستخدم Java كائنات فئة لتنفيذ RTTI ، حتى لو كنت تقوم بعمليات مثل تحويل النوع.
سيقوم كل فئة بإنشاء كائن فئة مقابل ، يتم حفظه في ملف .class. يتم تحميل جميع الفئات ديناميكيًا إلى JVM عند استخدامها لأول مرة. سيتم تحميل هذا الفصل عندما ينشئ البرنامج إشارة إلى عضو ثابت في الفصل. يتم تحميل كائنات الفئة فقط عند الحاجة ، ويتم تنفيذ التهيئة الثابتة عند تحميل الفصل.
الفئة العامة testmain {public static void main (string [] args) {system.out.println (xyz.name) ؛}} class xyz {public static string name = "luoxn28 ؛ شيدت ") ؛}}نتيجة الإخراج هي:
يتحقق Loader أولاً ما إذا كان كائن الفئة في هذه الفئة قد تم تحميله. إذا لم يتم تحميله ، فسيبحث محمل الفئة الافتراضية عن ملف .class المقابل بناءً على اسم الفئة.
لاستخدام معلومات النوع في وقت التشغيل ، يجب عليك الحصول على مرجع إلى كائن الفئة للكائن (مثل كائن أساسي). يمكنك استخدام Class.forname ("base") لتحقيق ذلك ، أو استخدام base.class. لاحظ أنه مثير للاهتمام. عند استخدام الدالة ".class" لإنشاء مرجع إلى كائن فئة ، لن يتم تهيئة كائن الفئة تلقائيًا ، وسيقوم استخدام ForName () تلقائيًا تهيئة كائن الفئة. الاستعدادات لاستخدام الفصول بشكل عام لديها الخطوات الثلاث التالية:
• التحميل: مكتمل بواسطة محمل الفئة ، ابحث عن رمز bytecode المقابل ، وإنشاء كائن فئة
• الرابط: تحقق من رمز bytecons في الفصل وقم بتخصيص مساحة للمجال الثابت
• التهيئة: إذا كان للفئة فئة فائقة ، فسيتم تهيئتها ، ويتم تنفيذ التهيئة الثابتة وكتلة التهيئة الثابتة.
قاعدة الفئة العامة {static int num = 1 ؛ static {system.out.println ("base" + num) ؛}} الفئة العامة الرئيسية {public static void main (string [] args) {// static blocks لن يتم تهيئة clazz2 clazz2 = base.class ؛ system.out.println ("---------") class.forname ("zzz.base") ؛}} 2. تحقق قبل تحويل الكتابة
سيقوم المترجم بالتحقق مما إذا كان الانتقال إلى أسفل النوع قانونيًا ، وإذا لم يكن قانونيًا ، فسيتم طرح استثناء. قبل تحويل النوع لأسفل ، يمكنك استخدام extryof للحكم.
الفئة الفئة {} الفئة المشتقة تمتد قاعدة {} الفئة العامة الرئيسية {public static void main (string [] args) {base base = new derived () ؛ if (base extryof desired) {// here ye you ad system.out.println ("ok") ؛ 3. الانعكاس: معلومات وقت التشغيل
إذا كنت لا تعرف النوع الدقيق للكائن ، يمكن أن يخبرك RTTI ، ولكن هناك شرط أساسي: يجب أن يكون هذا النوع معروفًا في وقت الترجمة بحيث يمكن استخدام RTTI لتحديده. يدعم الفصل الدراسي التفكير مع مكتبة فئة java.lang.reflect. تحتوي مكتبة الفصل هذه على فئات الحقل والطريقة والمنشأة. يتم إنشاء كائنات هذه الفئات بواسطة JVM عند بدء التشغيل لتمثيل الأعضاء المقابلة في فئات غير معروفة. وبهذه الطريقة ، يمكنك استخدام المسكن لإنشاء كائن جديد ، واستخدام طرق GET () وتعيين () للحصول على وتعديل الحقول المرتبطة بكائن الحقل في الفصل ، واستخدام طريقة Invoke () لاستدعاء الطريقة المرتبطة بكائن الطريقة. بالإضافة إلى ذلك ، يمكن أيضًا استدعاء العديد من الأساليب المريحة مثل getFields () و getMethods () و getConstructors () لإرجاع صفيف يمثل الحقول والأساليب وكائنات المنشئ. وبهذه الطريقة ، يمكن تحديد معلومات الكائن بالكامل في وقت التشغيل دون معرفة أي شيء عن الفصل في وقت الترجمة.
لا يوجد شيء سحري حول آلية الانعكاس. عند التعامل مع كائن من النوع غير المعروف من خلال التفكير ، يقوم JVM ببساطة بفحص الكائن لمعرفة فئة محددة تنتمي إليها. لذلك ، يجب أن تكون class من تلك الفئة قابلة للإنشاء لـ JVM ، إما على الجهاز المحلي أو من الشبكة. لذا فإن الفرق الحقيقي بين RTTI والانعكاس هو فقط:
• RTTI ، يفتح المترجم ويتحقق من ملفات .class في وقت الترجمة
• تعكس وفتح والتحقق من ملفات .class في وقت التشغيل
الشخص العام من الفئة العامة ينفذ قابلة للتسلسل {اسم السلسلة الخاصة ؛ العصر الخاص ؛ // get/set method} public static void main (string [] args) {person person = new شخص ("luoxn28" ، 23) ؛ class clazz = person.getClass () field.getName () ؛ propertyDescriptor descriptor = new propertyDescriptor (مفتاح ، clazz) ؛ طريقة طريقة = واصف. استدعاء أعلاه وظيفة الحصول على الفئة من خلال طريقة getReadMethod () ، ويمكن استخدام طريقة getWriteMethod () لاستدعاء طريقة المجموعة للفئة. بشكل عام ، لا نحتاج إلى استخدام أدوات الانعكاس ، لكنها أكثر فائدة في إنشاء رمز ديناميكي. يتم استخدام الانعكاس في Java لدعم ميزات أخرى مثل تسلسل الكائنات وجافابانز.
4. العامل الديناميكي
يتمثل وضع الوكيل في توفير عمليات إضافية أو مختلفة ، ويتم استخدام الكائنات المدرجة لاستبدال الكائنات "الفعلية" ، والتي تتضمن التواصل مع الكائنات "الفعلية" ، وبالتالي فإن الوكيل يعمل عادة كوسيط. إن الوكيل الديناميكي لـ Java هو خطوة واحدة على فكرة الوكيل ، والتي يمكن أن تنشئ بشكل ديناميكي والمكالمات والتعامل مع المكالمات مع أساليب الوكيل ديناميكيًا. يتم إعادة توجيه جميع المكالمات التي تم إجراؤها على الوكيل الديناميكي إلى معالج مكالمات واحد ، وتتمثل وظيفتها في الكشف عن نوع المكالمة وتحديد السياسة المقابلة. فيما يلي مثال على الوكيل الديناميكي:
فئات الواجهة والنفايات:
واجهة الواجهة العامة {void dosomething () ؛ void somethingelse (String arg) ؛} تنفذ الفئة العامة realObject Interface {public void dosomething () {system.out.println ("dosomething.") ؛ معالج كائن الوكيل الديناميكي:
الطبقة العامة DynamicProxyHandler تنفذ invocationHandler {private Object Proxyed ؛ public DynamicProxyHandler (proxyed) {this.proxyed = proxyed ؛}@Overridepublic invoke (proxy object ، method ، method [] args [] args) Proxy يعمل. ") ؛ طريقة الإرجاع. فئة الاختبار:
الفئة العامة الرئيسية {public static void main (string [] args) {realObject Real = new aralObject () ؛ واجهة proxy = (interface) proxy.newproxyinstance (interface.class.getClassloader () ، فئة جديدة [] {interface.class} ، جديد DynamicProxyHandler (Real)) ؛ proxy.dosomething () ؛ proxy.SomethingElse ("Luoxn28") ؛}}نتيجة الإخراج على النحو التالي:
يمكنك إنشاء وكيل ديناميكي عن طريق استدعاء طريقة الوكيل الثابت proxy.newproxyinstance (). تتطلب هذه الطريقة محمل فئة ، وقائمة من الواجهات التي تريد تنفيذ الوكيل (وليس فئة أو فئة مجردة) ، وفئة تنفيذ من invocationHandler. يمكن للوكالة الديناميكية إعادة توجيه جميع المكالمات إلى معالج الاتصال ، وبالتالي فإن مُنشئ معالج الاتصال عادة ما يمرر مرجعًا إلى الكائن "الفعلي" ، والذي سيقوم بإعادة توجيه الطلب عندما يقوم معالج الاتصال بمهمة الوساطة.
ما سبق هو الفهم المتعمق لانعكاس Java الذي أدخله المحرر لك. آمل أن يكون ذلك مفيدًا لك. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر إليك في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!