غالبًا ما نرى أشياء مثل "Override" و "Target" وما إلى ذلك في رمز Java. ما هي هذه؟
في جافا هم "التعليقات التوضيحية".
فيما يلي شرح Baidu Encyclopedia: java.lang.annotation. سيترك برنامج التحويل البرمجي معلومات التعليقات التوضيحية في أرشيف الفصل ، ولكن لا يقرأه الجهاز الظاهري ، ولكنه يوفر المعلومات فقط عند تشغيل برنامج التحويل البرمجي أو الأداة.
بمعنى آخر ، تعتمد التعليقات التوضيحية على ملفات الفصل ، ولها نفس تأثير وحدات الماكرو بلغة C.
لا يوجد أي أثر للشرح في ملف الفصل.
أساس التعليق التوضيحي هو انعكاس. لذلك ، يمكن فهم التعليق التوضيحي كمفهوم فريد لجافا.
1. ملاحظة ميتا
في حزمة java.lang.annotation ، تم تعريف أربعة "بدائية" من التعليقات التوضيحية.
1).@Target ، يستخدم لتوضيح النوع الذي يتم تعديله: (الأساليب ، الحقول ، الفئات ، الواجهات ، إلخ)
2).@الاستبقاء ، يصف وجود annentation:
سيكون هناك تعليق توضيحي attreencepolicy.runtime في ملف Bytecode Class ويمكن الحصول عليه من خلال التفكير في وقت التشغيل.
attreencePolicy.class سياسة الاستبقاء الافتراضية ، سيكون التوضيح موجودًا في ملف Bytecode الفصل ، ولكن لا يمكن الحصول عليه أثناء وقت التشغيل.
يوجد توضيح attreencepolicy.source فقط في الكود المصدري ولا يحتوي عليه في ملف الفئة Bytecode.
3).@موثقة ، بشكل افتراضي ، لن يتم تسجيل التعليقات التوضيحية في Javadoc ، ولكن يمكن استخدام هذا التعليقات التوضيحية للإشارة إلى أن هذا التعليق يجب تسجيله.
4).
إذا تم استخدام نوع شرح باستخدام تعديل inherited لفئة ، فسيتم استخدام التعليق التوضيحي لفئة فرعية من الفصل.
2. التعليقات التوضيحية المخصصة
package com.joyfulmath.jvmexample.annnotaion ؛ import java.lang.annotation.elementtype ؛ import java.lang.annotation.retention ؛ import java.lang.annotation. 13:36*/@target (elementType.Field)@repinention (attreentionpolicy.runtime) public interface fruitname {string value () الافتراضي "" ؛} بادئ ذي بدء ، يتطلب التعليقات التوضيحية عمومًا تعديلات التعليقات التعليمية التعويضية:
target (elementType.field)
@الاحتفاظ (attreentionpolicy.runtime)
تم شرح الوظائف المحددة أعلاه.
سيكون لجميع التعليقات التوضيحية قسم مشابه لـ "Func". يمكن فهم ذلك كمعلمة شرح.
package com.joyfulmath.jvmexample.annnotaion ؛ استيراد com.joyfulmath.jvmexample.tracelog ؛/*** Author deman.lu*version على 2016-05-23 13: 37*/public class Apple {fruitname ("Apple") سجل هذا الرمز:
05-23 13: 39: 38.780 26792-26792/com.joyfulmath.jvmexample I/Apple: displayapplename: null [at (Apple.java:16)]
لماذا لم تنجح المهمة؟ كيفية تعيين الملف للشرح "Apple"؟ كيفية القيام بذلك إذا لم يعرف المترجم حتى الآن.
3. معالج التعليقات التوضيحية
نحتاج أيضًا إلى معالج لشرح كيفية عمل التعليقات التوضيحية ، وإلا فسيكون ذلك هو نفس التعليقات التوضيحية.
من خلال التفكير ، يمكن الحصول على محتوى التعليقات التوضيحية:
package com.joyfulmath.jvmexample.annnotaion ؛ استيراد com.joyfulmath.jvmexample.tracelog ؛ استيراد java.lang.reflect.field ؛/*** @author deman.lu*voide on 2016-05-23 14: 08*/public class fruitins {public static void <؟ = "" ؛ الحقل [] الحقول = clazz.getDeclaredFields () ؛ لـ (الحقل الحقل: الحقول) {if (field.isannotationpresent (fruitname.class)) {fruitnameهذا هو الاستخدام العام للشروح.
تحليل إطار التعليق التوضيحي Android
كما يتضح من ما سبق ، فإن استخدام أطر التعليقات التوضيحية يتطلب بشكل أساسي التفكير.
ولكن إذا استخدمت إطار التعليق التوضيحي مع وظيفة الانعكاس ، فقد أستخدمه أيضًا مباشرة ، فهو أكثر بساطة.
إذا كانت هناك آلية ، فيمكنها تجنب كتابة الكثير من الكود المماثل المكرر ، خاصة أثناء تطوير Android ، ويقابل عدد كبير من FindViewById & Onclick وغيرها من الأحداث.
نمط الكود متسق ، لكن الرمز مختلف. في هذا الوقت ، يمكن أن يؤدي استخدام إطار التعليق التوضيحي إلى توفير الكثير من وقت التطوير ، وبالطبع ، سيزيد من النفقات العامة الأخرى وفقًا لذلك.
فيما يلي مثال على استخدام butterknife:
BindString (R.String.login_error)
سلسلة loginerrormessage.
يبدو الأمر بسيطًا جدًا ، فهو تعيين سلسلة للقيمة الأولية المقابلة لسلسلة الدقة. بهذه الطريقة يمكنك توفير بعض الوقت. بالطبع هذا مجرد مثال.
إذا كنت تستخدم التعليقات التوضيحية الأخرى بشكل كبير ، فيمكنك توفير الكثير من وقت التطوير.
دعونا نرى كيف يتم تنفيذها:
حزمة butterknife ؛ استيراد Android.support.annotation.stringres ؛ import java.lang.annotation.retention ؛ import java.lang.annotation.target ؛ استيراد java.lang.annotation <pre> <code>* {literal @} bindString (R.String.userName_error) سلسلة usernameRrortext ؛* </code> </pre>*/ @entrention (class) target (field) public interface bindString {/** string morder معرف الحقل. */@stringres int value () ؛} يحتوي BINDSTRING على معلمة واحدة فقط ، القيمة ، أي تعيين القيمة إلى stringRes.
كما هو مذكور أعلاه ، ما سبق هو المكان الذي يتم فيه تحديد التعليق التوضيحي واستخدامه ، لكن التفسير الحقيقي للشرح هو كما يلي: ButterNifeProcessor
خريطة خاصة <typeelement ، bindingclass> findandParsetArgets (ENVENVIRENMENT)
هذه الوظيفة تعترض بعض التعليمات البرمجية:
// معالجة كل عنصر bindString.for (العنصر العنصر: Env.GetElementAntAtenTedWith (bindString.Class)) {if (! superficialididation.valideElement (element)) ه) ؛}} ابحث عن جميع عناصر التعليقات التوضيحية BindString وابدأ في التحليل:
Private void parseresourcestring (عنصر العنصر ، الخريطة <typeelement ، bindingclass> targetclassmap ، set <TypeElement> eracedTargetNames) {boolean haserror = false ؛ typeelement exprosingelement = (typeElement) element.getenCloseElement () ؛ (! string_type.equals (element.astype (). القيود. element.getAnnotation (bindString.class) .value () خطأ) ؛ bindingclass.addresource (الربط) ؛ EratedTargetNames.Add (evingelement) ؛} تحقق أولاً مما إذا كان العنصر هو نوع سلسلة.
// تجميع المعلومات على field.String اسم = element.getSimplename ().
احصل على اسم الحقل ومعرف السلسلة.
أخير
خريطة <typeElement ، bindingClass> TargetClassMap
يتم تخزين العناصر وأوصاف التعليقات التوضيحية واحدة تلو الأخرى في الخريطة.
Override Public Boolean Process (set <؟ Extends TypeElement> عناصر ، البيئة المستديرة env) {map <typeElement ، bindingClass> targetClassMap = findAndParsetArgets (env) ؛ for (map.entry <typeElement ، bindingClass> الإدخال: targetclassmap.entryset () Entry.getValue () ؛ حاول {bindingclass.brewjava (). writeto (filer) ؛} catch (ioException e) {error (typeElement ، "غير قادر على كتابة Binder binder for type ٪ s: ٪ s" ، typelement ، e.getMessage ()) ؛}} retrue ؛} هذا هو المكان الذي يتم فيه بدء إطار التعليقات التوضيحية ، وهي عملية مستقلة. لن تدرس هذه المقالة التفاصيل المحددة ، فقط مسحها ، هذا هو المكان الذي يحركه الإطار.
من المعلومات أعلاه ، يتم تخزين جميع معلومات التعليقات التوضيحية في TargetClassMap.
يجب أن يكون الكود الذي تم وضع علامة عليه باللون الأحمر أعلاه هو جوهر إطار التعليقات التوضيحية.
منذ Java SE5 ، قدمت Java أداة APT ، والتي يمكنها معالجة التعليقات التوضيحية. Java SE6 تدعم معالج التعليقات التوضيحية الموسعة.
والمعالجة عدة مرات أثناء التجميع. يمكننا استخدام معالج شرح مخصص لإنشاء رمز Java جديد وفقًا للقواعد عند تجميع Java .
javafile brewjava () {typespec.builder result = typespec.classbuilder (endendedClassName) .addModifiers (public) ؛ if (isfinal) {result.addModifiers (modifier.final) ؛} else {result.addtypevariable (typevariablename.get ("t" ، targettypename)) ؛} typename targettype = isfinal؟ TargetTyPename: typevariablename.get ("T") ؛ if (hasparentBinding ()) {result.superClass (parameterizedTyPename.get (parentBinding.generatedClassName ، targetType)) ؛} {result.addsuperInterface (createBindMeThoD (targettype) ؛ if (isGeneratingUnbinder ()) {result.addtype (createUnbinderClass (targettype)) ؛} آخر إذا (! isfinal) {result.addmethod (createBindToTargetMeThod () من زبدة سكين. مفتاح هذا المقطع هو إنشاء ملف جديد.
ثم اكتب المحتوى ذي الصلة.