قمت بمراجعة رمز لزميلي قبل يومين. شعرت أنه لم يكن لدي فهم جيد من جافا جيرلسيك ، لذلك أخرجت كتاب "جافا الفعالة" 1 ثم نظرت إلى الفصول ذات الصلة. في البند 24: القضاء على قسم التحذيرات غير المحددة ، يستخدم المؤلف طريقة <T> t [] Tararray (t [] A) في فئة ArrayList كمثال لتوضيح كيفية استخدام @suppresswarnings للمتغيرات.
ArrayList هي فئة عامة ، والتي تم إعلانها مثل هذا:
Javapublic Class ArrayList <e> يمتد قائمة التجريدية <e> قائمة <e> ، عشوائي ، clonable ، java.io.serializable
طريقة tararray (t [] a) من هذه الفئة هي طريقة عامة ، يتم إعلانها وتنفيذها على هذا النحو:
suppresswarnings ("غير محدد") عام <t> t [] tararray (t [] a) {if (A.Length <size) // قم بعمل مجموعة جديدة من نوع وقت التشغيل A ، لكن محتوياتاتي: return (t []) arrays.copyof (elementData ، size ، a.getClass () ؛ الحجم) a [size] = null ؛ return a ؛} تم الإعلان عن هذه الطريقة بالفعل في واجهة التجميع. نظرًا لأننا نستخدمه غالبًا من خلال ArrayList ، فسنستخدم ArrayList كمثال هنا.
1 لماذا تم إعلانه كنوع مختلف؟
سؤالي هو: لماذا تستخدم هذه الطريقة النوع T بدلاً من النوع E من ArrayList؟ هذا هو ، لماذا لا تعلن هذه الطريقة مثل هذه:
javapublic e [] tararray (e [] a) ؛
إذا كانت الأنواع هي نفسها ، فيمكن العثور على خطأ نوع المعلمة أثناء التجميع. إذا كانت الأنواع مختلفة ، فمن السهل إنشاء أخطاء وقت التشغيل. على سبيل المثال ، الكود التالي:
// إنشاء ArrayListList <string> strlist = new ArrayList <Tring> () ؛ strlist.add ("ABC") ؛ strlist.add ("xyz") ؛ // تحويل strlist الحالي إلى مجموعة رقم. لاحظ أنه لا توجد أخطاء تجميع في العبارة التالية. الرقم [] numarray = strlist.toarray (رقم جديد [0]) ؛ قم بتشغيل الكود أعلاه والخط 6 سوف يرمي استثناء java.lang.arraystoreException.
إذا كانت طريقة ToArray تستخدم النوع E ، فسيقوم العبارة 2 بإنشاء خطأ في التجميع. أخطاء التجميع أكثر ودية من أخطاء وقت التشغيل. علاوة على ذلك ، فإن الغرض الرئيسي من الأدوية الأدوية هو التخلص من أخطاء تحويل النوع (ClassCastException) أثناء التجميع. هذه الطريقة عكس ذلك. هل هذا خطأ كبير؟ لقد واجهت حشرة جافا ، لكن ما زلت لا أستطيع تصديق ذلك.
بعد التحقق من الإنترنت ، تمت مناقشة هذه المشكلة عدة مرات 2 ، 3 ، 4.
2 يمكن أن تحسن المرونة
هذا الإعلان أكثر مرونة ويمكنه تحويل العناصر في القائمة الحالية إلى مجموعة من الأنواع الأكثر عمومية. على سبيل المثال ، نوع القائمة الحالي هو عدد صحيح ، ويمكننا تحويل عناصره إلى مجموعة أرقام.
قائمة <integer> intlist = new ArrayList <integer> () ؛ intlist.add (1) ؛ intlist.add (2) ؛ number [] numarray = intlist.toarray (رقم جديد [0]) ؛
إذا تم الإعلان عن هذه الطريقة كنوع E ، فسيكون للرمز أعلاه خطأ في التجميع. يبدو أنه سيكون من الأنسب إعلان الطريقة على النحو التالي:
javapublic <t super e> t [] tararray (t [] a) ؛
ومع ذلك ، فإن بناء الجملة مثل <t super e> غير موجود في Java. وحتى لو كان موجودًا ، فإنه لا يعمل في المصفوفات. ولهذا السبب أيضًا ، عند استخدام هذه الطريقة ، حتى لو كانت T هي الفئة الأصل لـ E ، أو T هي نفس E ، Java.lang.arrayStoreException 5 ، 6 ، 7 لا يمكن تجنبها تمامًا. يرجى الاطلاع على الرموبين التاليين. في الكود الأول ، تتمثل T في الفئة الأصل لـ E ، وفي الرمز الثاني ، T هي نفس E. كلا القطعان من استثناءات الرمز.
الرمز 1:
قائمة <integer> intlist = new ArrayList <integer> () ؛ intlist.add (1) ؛ intlist.add (2) ؛ تعويم [] floatarray = تعويم جديد [2] ؛ // تعويم هو فئة فرعية من العدد ، لذلك تعويم [] هي فئة فرعية من الرقم [] numarray = floatarray ؛ // سوف يرمي البيان التالي استثناء ArrayStoreException numarray = intlist.toarray (numarray) ؛
الرمز 2:
قائمة <murble> intlist = new ArrayList <mumber> () ؛ // نوع القائمة هو الرقم. لكن الرقم هو فئة مجردة ، ويمكن فقط تخزين مثيلات من فئة الفئة الفرعية inte. intlist.add (عدد صحيح جديد ()) ؛ تعويم [] floatarray = تعويم جديد [] ؛ // تعويم هو فئة فرعية من الرقم ، لذلك تعويم [] هي فئة فرعية من الرقم [] [] numarray = floatarray ؛ // سوف يلقي البيان التالي استثناء arraystoreException numarray = intlist.toarray (numarray) ؛
كل الاستثناءات المذكورة أعلاه ناتجة عن هذه الحقيقة: إذا كانت A هي الفئة الأصل من B ، فإن A [] هي الفئة الوالدية لـ B []. جميع الفئات في Java ترث من الكائن ، والكائن [] هي الفئة الأصل لجميع المصفوفات.
يعطي هذا المنشور 8 مثالاً ، يوضح أنه حتى إذا تم الإعلان عن نوع هذه الطريقة على أنه E ، فلا يمكن تجنب ArrayStoreException.
هذا الاستثناء مذكور أيضًا في وثائق هذه الطريقة:
ArrayStoreException إذا كان نوع وقت التشغيل من الصفيف المحدد ليس من النوع الخارق لنوع وقت التشغيل لكل عنصر في هذه القائمة.
3 يمكن أن تكون متوافقة مع الإصدارات قبل Java 1.5
ظهرت هذه الطريقة قبل إدخال الأدوية الجيرية في Java (تم تقديم Generics في JDK1.5). تم إعلانه في ذلك الوقت:
كائن جافابلوبال
بعد ظهور الأدوية ، تصبح العديد من الفئات والأساليب عامة. تعلن هذه الطريقة أيضًا مثل هذا:
Javapublic <T> t [] tararray (t [] أ)
هذا الإعلان متوافق مع الإصدارات قبل Java 1.5.
4 بضع كلمات أخرى
تتطلب هذه الطريقة معلمة صفيف. إذا كان طول هذه الصفيف أكبر من أو يساوي حجم القائمة الحالية ، فسيتم تخزين العناصر الموجودة في القائمة في الصفيف ؛ إذا كان طول هذه الصفيف أقل من حجم القائمة الحالية ، فسيتم إنشاء صفيف جديد وسيتم تخزين العناصر الموجودة في القائمة الحالية في الصفيف الذي تم إنشاؤه حديثًا. لتحسين الكفاءة ، إن أمكن ، يجب أن يكون طول الصفيف الذي تم تمريره أكبر من أو يساوي حجم القائمة لتجنب إنشاء صفيف جديد بهذه الطريقة.
قائمة <integer> intlist = new ArrayList <integer> () ؛ intlist.add () ؛ intlist.add () ؛ // لصق في صفيف ، طوله هو رقم [] numarray = intlist.toarray (رقم جديد []) ؛ // بيان // لصق في صفيف ، فإن طوله يساوي طول رقم القائمة [] NumArray = intlist.toarray (رقم جديد [intlist.size ()]) ؛ //إفادة
بالإضافة إلى ذلك ، لا يمكن أن تكون الصفيف كمعلمات فارغة ، وإلا سيتم طرح nullpointerxception.
الحواشي:
1
جافا فعالة (الطبعة الثانية)
2
وصلة
3
وصلة
4
وصلة
5
وصلة
6
وصلة
7
وصلة
8
وصلة
9
وصلة
10
وصلة
تم إنشاؤه: 2016-04-06 الأربعاء 21:14
emacs 24.5.1 (وضع ORG 8.2.10)
التحقق
المحتوى أعلاه هو السبب في أن نوع المعلمة من طريقة java arraylist.toarray (t []) التي قدمها لك المحرر هي T بدلاً من E. آمل أن تكون مفيدة للجميع!