الأدوية
الحد من العناصر في مجموعة إلى نوع معين.
على المدى
بعض الملاحظات:
الأنواع المعلمة والأنواع البدائية متوافقة مع بعضها البعض
ArrayList Collection1 = new ArrayList <integer> () ؛ // pass ، لا يوجد warningarraylist <integer> collection2 = new ArrayList () ؛ // pass ، هناك تحذير
الأنواع المعلمة لا تعتبر علاقات الميراث من المعلمات النوع
ArrayList <String> collection3 = new ArrayList <Object> () ؛ // لا تمر التجميع ArrayList <Object> collection4 = new ArrayList <String> () ؛ // لا تمر التجميع
لكن
ArrayList Collection5 = جديد ArrayList <integer> () ؛ ArrayList <String> Collection6 = Collection5 ؛ // تم تجميعه بواسطة
"؟" البرية
"؟" يعني أي نوع. استخدم "؟" حرف Wildcard للإشارة إلى أنواع مختلفة من المعلمة. يمكن أن تستدعي طرقًا غير مرتبطة بترويج المعلمات (مثل طريقة Size ()) ، ولا يمكنها استدعاء طرق المرتبطة بالمعلمات (مثل طريقة Add ())
امتداد البرية
تأهل الحدود العليا لأحرف البطاقة البرية
arraylist <؟ يمتد الرقم> collection1 = new ArrayList <integer> () ؛ // compile by ArrayList <؟ يمتد الرقم> collection2 = new ArrayList <String> () ؛ // compile by not
تأهل الحدود السفلية لأحرف البطاقة البرية
arraylist <؟ super integer> collection3 = new ArrayList <Number> () ؛ // compile by ArrayList <؟ super integer> collection4 = new ArrayList <string> ()
طرق عامة مخصصة
وظائف قالب C ++
القالب <class t> t add (t x ، t y) {return (t) (x+y) ؛}يتم تنفيذ جافا جيرلسيس بشكل أساسي بالكامل في المترجم ، ويستخدمه المترجم لإجراء عمليات فحص النوع وأحكام الكتابة ، ثم إنشاء رمز bytecode غير العادي. تقنية التنفيذ هذه هي "محو".
مثيل "محو"
يتم توفير الأدوية العامة إلى برنامج التحويل البرمجي Javac لتحديد نوع الإدخال للجمع. عندما يقوم المترجم بتجميع مجموعة مع وصف النوع ، ستتم إزالة معلومات "النوع".
الطبقة العامة generictest {public static void main (string [] args) {new Generictest (). TestType () ؛ } public void testtype () {ArrayList <integer> collection1 = new ArrayList <integer> () ؛ ArrayList <string> collection2 = new ArrayList <String> () ؛ System.out.println (collection1.getClass () == collection2.getClass ()) ؛ // أنواع الفئة من الاثنين هي نفسها ، أي ، رمز bytecode هو نفس النظام. // الفئة هي java.util.arraylist ، ولا توجد معلومات معلمة نوع فعلية}}الإخراج
حقيقي
java.util.arraylist
استخدم الانعكاس لتخطي المترجم وإضافة أنواع أخرى من البيانات إلى مجموعة عامة.
يمكن استخدام أنواع المرجع فقط كمعلمات فعلية للطرق العامة:
الفئة العامة generictest {public static void main (string [] args) {swap (سلسلة جديدة [] {"111" ، "222" ، 0،1) ؛ // compile by // swap (new int [] {1،2} ، 0،1) ؛ // ترجمة عن طريق عدم التجميع لأن int ليس هو تبديل نوع المرجع (عدد صحيح جديد [] {1،2} ، 0،1) ؛ // الترويج بواسطة}/*تبديل عناصر I-Th و JTH من Array A*/Public Static <T> swap void (t [] A ، int I ، int j) {t temp = a [i] ؛ a [i] = a [j] ؛ A [j] = temp ؛ }}ولكن لاحظ أنه يمكن استخدام الأنواع الأساسية في بعض الأحيان كمعلمات فعلية ، لأن هناك تعبئة تلقائية وملاءمة. مثال (تم تجميعه وتمريره):
الطبقة العامة generictest {public static void main (string [] args) {new Generictest (). TestType () ؛ int a = biggerone (3،5) ؛ // int and double ، احصل على التبادل كرقم رقم B = Biggerone (3،5.5) ؛ // string و int الحصول على التبادل ككائن كائن c = biggerone ("1" ، 2) ؛ } // return y من x ، y public static <T> t biggerone (t x ، t y) {return y ؛ }}في الوقت نفسه ، يوضح هذا المثال أيضًا أنه عندما تكون المعلمات الفعلية غير متناسقة ، فإن T يأخذ التقاطع ، أي أول فئة الوالدين المشتركة. بالإضافة إلى ذلك ، إذا كنت تستخدم الرقم B = Biggerone (3،5.5) ؛ إلى سلسلة C = Biggerone (3،5.5) ؛ ثم يتم الإبلاغ عن خطأ التجميع:
خطأ: (17 ، 29) Java: الأنواع غير المتوافقة: الأنواع المستخلصة لا تفي بالاستدلال العلوي: java.lang.number & java.lang.comparable <؟ يمتد java.lang.number & java.lang.comparable <؟ >>
الحد الأعلى: java.lang.string ، java.lang.object
ولكن هناك شيء واحد لم أفهمه. أنا أخطئ في تصحيح الأخطاء في الفكرة ووجدت أن النتيجة هي كما يلي: لقطة الشاشة العامة لتصحيح الأخطاء-لا أعرف لماذا يكون B من النوع مزدوجًا (ولكنه سيقوم بتجميع خطأ عند استلام قيمة الإرجاع على مزدوج B). لا أعرف ما إذا كان له أي علاقة مع IDE. هل يعرض IDE أكثر أنواع هذا الكائن دقة عند تصحيح الأخطاء؟
اكتب معلمات النوع
تسمى العملية التي يحكم بها المترجم أن المعلمات الفعلية للطريقة العامة تسمى استنتاج النوع.
عندما يتم تطبيق متغير نوع معين فقط واحد من جميع المعلمات وقيم الإرجاع في قائمة المعلمات بأكملها ، يتم تحديده بناءً على نوع التطبيق الفعلي في ذلك الوقت عندما يتم استدعاء الطريقة. أي أن نوع المعلمات العامة يتم تحديده مباشرة بناءً على نوع المعلمة أو قيمة الإرجاع التي تم تمريرها عند استدعاء الطريقة. على سبيل المثال:
Swap (سلسلة جديدة [3] ، 1،2) -> ثابت <e> تبديل الفراغ (E [] A ، int I ، Int J)
عندما يتم تطبيق متغير النوع في أماكن متعددة في جميع المعلمات وقيم إرجاع قائمة المعلمات بأكملها ، إذا كانت العديد من أنواع التطبيق الفعلية تتوافق مع نفس النوع عند استدعاء الطريقة ، فإن نوع المعلمة العامة هو هذا النوع. على سبيل المثال:
إضافة (3،5) -> ثابت <t> t إضافة (T A ، T B)
عندما يتم تطبيق متغير نوع معين في العديد من الأماكن في جميع المعلمات وقيم الإرجاع في قائمة المعلمات بأكملها ، إذا كانت أنواع التطبيق الفعلية في العديد من الأماكن تتوافق مع أنواع مختلفة عند استدعاء الطريقة ولا توجد قيمة إرجاع ، فإن الحد الأقصى للمعلمات التقاطع بين المعلمات المتعددة ، أي أول فئة الوالد الشائعة. على سبيل المثال:
ملء (عدد صحيح جديد [3] ، 3.5) -> static <t> foid fill (t a [] ، t v)
النوع الفعلي المقابل لهذا المثال هو الرقم ، ومجمعه وتشغيل المشكلات.
عندما يتم تطبيق متغير نوع في أماكن متعددة في جميع المعلمات وقيم الإرجاع لقائمة المعلمات بأكملها ، إذا كانت أنواع التطبيق الفعلية في العديد من الأماكن تتوافق مع أنواع مختلفة عند استدعاء الطريقة ، وهناك قيمة إرجاع ، يتم إعطاء نوع قيمة الإرجاع الأولوية ، على سبيل المثال: على سبيل المثال:
int x = add (3،3.5) -> static <t> t add (t a ، t b)
كما أبلغ الخطأ الذي تم تجميعه أعلاه ، ويتم تغيير نوع X إلى Float أيضًا عن خطأ ، ويكون التغيير إلى الرقم ناجحًا.
أمثلة على نوع الاستدلال لأنواع المعلمات متعدية:
نسخة (عدد صحيح جديد [5] ، سلسلة جديدة [5]) -> ثابت <T> نسخة باطلة (t [] a ، t [] b)
هذا المثال يثير أن نوع المعلمة الفعلي هو كائن وتجميعه.
نسخ (ArrayList جديد <string> ، عدد صحيح جديد [5]) -> ثابت <T> نسخة باطلة (مجموعة <T> A ، T [] B)
يحدد هذا المثال مباشرة متغير النوع كنوع سلسلة استنادًا إلى مثيل فئة ArrayList المعلمة ، ويبلغ عن خطأ في التجميع.
فصول عامة مخصصة
مثال
الفئة العامة genericdao <t> {public void add (t x) {} pincial t findbyid (int id) {return null ؛ } void public delete (t obj) {} public void delete (int id) {} public void update (t obj) {} pincerbyusername (اسم السلسلة) {return null ؛ } public <t> set <T> findByConditions (string where) {return null ؛ }}ملاحظة: عندما يتم الإعلان عن متغير كجنرال ، لا يمكن استدعاؤه إلا من خلال متغيرات الأمثلة والأساليب (والأنواع المدمجة) ، ولكن ليس عن طريق المتغيرات الثابتة والطرق الساكنة. نظرًا لأن الأعضاء الثابتة يتم مشاركتهم بواسطة فئات معلمة ، يجب ألا يكون للأعضاء الثابتون معلمات نوع الفصل.
مقارنة بين الطرق العامة والفصول العامة
مثال:
الفئة العامة A <t> () {// Member Method of Generic Class ، يتم تقييد t من خلال t بعد temberfunc /{return null ؛ } // طريقة عامة ، هنا T و T تختلف عن t من الفئة A الثابتة العامة <T> t genericfunc (t a) {return null ؛ } public static void main (string [] args) {// marclized بدون تمرير // integer i = a <string> (). findbyusername ("s") ؛ // تم تجميعها بواسطة set <integer> set = a <string> (). findByConditions ("s") ؛ }}هنا integer i = a <string> (). findByuserName ("s") ؛ سوف يقوم بتجميع خطأ والإبلاغ عن خطأ:
خطأ: (35 ، 61) Java: النوع غير المتوافق: Java.lang.String لا يمكن تحويله إلى java.lang.integer
من هذا المثال ، يمكن ملاحظة أن T للطريقة العامة و T للفئة A مختلفة.
الأدوية والانعكاسات
الحصول على معلمات النوع الفعلي من عام من خلال الانعكاس
استخدم المتغيرات العامة كمعلمات للطريقة ، واستخدم طريقة getGenericParameterTypes لفئة الطريقة للحصول على مثال معلمة النوع الفعلي للعامة:
الطبقة العامة generictest {public static void main (string [] args) يلقي الاستثناء {getParamType () ؛ } /*استخدم الانعكاس للحصول على نوع المعلمة الفعلي لمعلمات الطريقة* / الفراغ الثابت العام getParamType () يلقي nosuchmethodexception {method method = cenerctest.class.getMethod ("applicMap" ، map.class) ؛ // احصل على نوع المعلمات العامة لنوع الطريقة [] أنواع = method.getGenericParameterTypes () ؛ System.out.println (أنواع [0]) ؛ // المعلمة نوع المعلمة pharizedtype ptype = (parameterizedType) أنواع [0] ؛ // primitive type system.out.println (ptype.getRawtype ()) ؛ // المعلمة النوع الفعلي system.out.println (ptype.getActualTyPearguments () [0]) ؛ System.out.println (ptype.getActualTyPearguments () [1]) ؛ } /* طريقة اختبار أنواع المعلمات* / الفراغ الثابت العام تطبيق (خريطة <integer ، سلسلة> خريطة) {}}نتيجة الإخراج:
java.util.map <java.lang.integer ، java.lang.string> interface java.util.mapclass java.lang.integerclass java.lang.string