حتى J2Se1.4 ، كان من المستحيل تحديد الأساليب مع المعلمات الحقيقية المتغيرة في برامج Java - لأن Java تتطلب أن يكون عدد وأنواع المعلمات الحقيقية (الوسيطات) والمعلمات الرسمية مطابقة واحدة تلو الأخرى ، ويتم إصلاح عدد المعلمات الرسمية عند تحديد الطريقة. على الرغم من أنه يمكن توفير نفس الطريقة مع عدد مختلف من المعلمات الرسمية من خلال آلية التحميل الزائد ، إلا أن هذا لا يزال لا يمكن تحقيق الغرض من السماح لكمية المعلمة الحقيقية بالتغيير بشكل تعسفي.
ومع ذلك ، فإن دلالات بعض الطرق تتطلب أن تكون قادرة على قبول عدد متغير من المعلمات الفعلية - على سبيل المثال ، يجب أن تكون الطريقة الرئيسية الشهيرة قادرة على قبول جميع معلمات سطر الأوامر كمعلمات فعلية ، ولا يمكن تحديد عدد معلمات سطر الأوامر مسبقًا.
بالنسبة لهذه المشكلة ، تقليديًا ، يتم استخدام ممارسة "استخدام صفيف لالتفاف المعلمات الفعلية المراد تمريرها" بشكل عام للتعامل معها.
1. لف المعلمات في صفيف
يمكن تقسيم ممارسة "التفاف المعلمات الفعلية مع المصفوفات" إلى ثلاث خطوات: أولاً ، تحديد معلمة من نوع الصفيف لهذه الطريقة ؛ ثم عند استدعاء ، قم بإنشاء صفيف يحتوي على جميع المعلمات الفعلية المراد تمريرها ؛ أخيرًا ، تمرير هذا الصفيف كمعلمة حقيقية.
يمكن أن يحقق هذا النهج بشكل فعال الغرض من "جعل الطريقة تقبل المعلمات المتغيرة" ، ولكن النموذج عند الاتصال ليس بسيطًا بما فيه الكفاية.
يتم توفير آلية Varargs في J2Se1.5 ، مما يسمح بالتعريف المباشر للمعلمات الرسمية التي يمكن أن تتطابق مع معلمات حقيقية متعددة. وبالتالي ، يمكن تمرير عدد متغير من المعلمات الفعلية بطريقة أبسط.
معنى varargs
بشكل عام ، "varargs" تعني "regiablenumberofarguments". في بعض الأحيان يطلق عليه ببساطة "regioblearguments" ، ولكن لأن هذا المصطلح لا يشير إلى ما هو متغير ، فإن المعنى غامض بعض الشيء.
2. تحديد طريقة مع معلمات حقيقية متغيرة
فقط أضف ثلاثة متتالية "." (على سبيل المثال ، "..." ، عجلات القطع في الجملة باللغة الإنجليزية) بين "النوع" و "اسم المعلمة" للمعلمة الرسمية ، ويمكن أن تتطابق مع معلمة فعلية غير مؤكدة. طريقة مع هذه المعلمات الرسمية هي طريقة ذات معلمات حقيقية متغيرة.
القائمة 1: طريقة ذات معلمات حقيقية متغيرة
ثابت خاص int sumup (int ... القيم) {}لاحظ أنه يمكن تعريف المعلمة الرسمية الأخيرة فقط على أنها "يمكن أن تتطابق مع معلمة فعلية غير مؤكدة". لذلك ، لا يمكن أن يكون هناك سوى معلمة رسمية من هذا القبيل بطريقة ما. بالإضافة إلى ذلك ، إذا كانت هذه الطريقة تحتوي على معلمات رسمية أخرى ، فضعها في الموضع الأمامي.
سيقوم برنامج التحويل البرمجي بتحويل المعلمة الرسمية الأخيرة إلى معلمة رسمية صفيف في سرية وتجعل علامة في ملف الفئة المترجمة للإشارة إلى أن هذه طريقة ذات معلمات حقيقية متغيرة.
القائمة 2: الشكل السري للطريقة مع معلمات حقيقية متغيرة
ثابت خاص int sumup (int [] القيم) {}بسبب مثل هذه التحولات ، من المستحيل تحديد طريقة لهذه الفئة التي تتوافق مع توقيع الطريقة المحولة.
القائمة 3: مجموعات من شأنها أن تسبب أخطاء التجميع
int static int sumup (int ... القيم) {} static int sumup (int [] القيم) {}3. استدعاء طريقة مع عدد متغير من المعلمات الحقيقية
طالما أن المعلمات الفعلية التي سيتم تمريرها تتم كتابة واحدة تلو الأخرى إلى الموضع المقابل ، يمكن استدعاء طريقة مع عدد متغير من المعلمات الحقيقية. لا توجد خطوات أخرى مطلوبة.
القائمة 4: يمكن تمرير العديد من المعلمات
sumUp(1,3,5,7);
بشكل غير مباشر ، سيقوم برنامج التحويل البرمجي بتحويل عملية الاتصال هذه إلى شكل "صفيف ملفوف في المعلمات الفعلية":
القائمة 5: ظهور سرا لإنشاء صفيف
sumUp(newint[]{1,2,3,4});
بالإضافة إلى ذلك ، يتضمن "غير مؤكد واحد" المذكور هنا أيضًا صفرًا ، لذا فإن هذه المكالمة معقولة:
القائمة 6: يمكنك أيضًا تمرير المعلمات الفعلية صفر
sumUp();
إن تأثير طريقة الاتصال هذه التي تم تحويلها سراً بواسطة المترجم يعادل هذا:
القائمة 7: الحجج الحقيقية صفر تتوافق مع المصفوفات الفارغة
sumUp(newint[]{});
لاحظ أن الماضي قد تم تمريره في هذا الوقت ، وليس لاغ. هذا يسمح بمعالجة شكل موحد دون الاضطرار إلى اكتشاف الموقف الذي ينتمي إليه.
4. معالجة المعلمات الفعلية بأرقام متغيرة
إن طريقة معالجة المعلمات الفعلية المرقمة المتغيرة هي نفس طريقة معالجة المعلمات الفعلية للمصفوفة. يتم حفظ جميع المعلمات الفعلية في صفيف مع نفس اسم المعلمات الرسمية. وفقًا للاحتياجات الفعلية ، بعد قراءة العناصر الموجودة في هذه الصفيف أو التبخير أو الطهي ، يمكنك فعل ما تريد.
القائمة 8: معالجة الحجج المستلمة
int static int sumup (int ... القيم) {int sum = 0 ؛ لـ (int i = 0 ؛ i <values.length ؛ i ++) {sum+= stable [i] ؛ } إرجاع مجموع ؛}5. إعادة توجيه العدد المتغير من المعلمات
في بعض الأحيان ، بعد قبول مجموعة من معلمات الأرقام المتغيرة ، يجب نقلها إلى طريقة رقم متغيرة أخرى. نظرًا لأن عدد المعلمات الفعلية المستلمة أثناء الترميز لا يمكن أن يكون معروفًا ، فإن ممارسة "كتابةها واحدًا تلو الآخر إلى الموقع الذي يجب أن تظهر" غير ممكن. ومع ذلك ، فإن هذا لا يعني أن هذه مهمة غير قابلة للتطبيق ، لأن هناك طريقة أخرى لاستدعاء طريقة ذات معلمات حقيقية متغيرة.
في عيون مترجم J2Se1.5 ، فإن الطريقة ذات المعلمات الحقيقية المتغيرة هي حالة خاصة للطريقة مع مجموعة من المعلمات الرسمية في النهاية. لذلك ، ضع مجموعة كاملة من المعلمات الفعلية لتمريرها في صفيف مسبقًا ، ثم تمرير هذه الصفيف كآخر معلمة فعلية إلى طريقة مع عدد متغير من المعلمات الحقيقية ، والتي لن تسبب أي أخطاء. مع هذه الميزة ، يمكن إكمال إعادة التوجيه بسلاسة.
القائمة 9: إعادة توجيه المعلمات الفعلية المستلمة
الفئة العامة printfsample {public static void main (string [] args) {printout ("pi: ٪ f e: ٪ f/n" ، math.pi ، math.e) ؛ } printout private static void (تنسيق السلسلة ، الكائن ... args) {system.out.printf (التنسيق ، args) ؛ }}6. هل هي صفيف؟ ليس صفيف؟
على الرغم من ذلك ، سيقوم برنامج التحويل البرمجي بتحويل المعلمات الرسمية التي يمكن أن تتطابق مع المعلمات الحقيقية غير المؤكدة إلى معلمات رسمية صفيف ؛ ويمكنه أيضًا استخدام صفيف للف المعلمات الفعلية ثم تمريرها إلى طريقة مع عدد متغير من المعلمات الحقيقية ؛ ومع ذلك ، هذا لا يعني أنه لا يوجد فرق بين "المعلمات الرسمية التي يمكن أن تتطابق مع المعلمات الحقيقية غير المؤكدة" و "المعلمات الرسمية الصفيف".
الاختلاف الواضح هو أنه إذا قمت باستدعاء طريقة هي آخر معلمة رسمية هي معلمة رسمية صفيف في شكل طريقة مع عدد متغير من المعلمات الحقيقية ، فسيؤدي ذلك فقط إلى خطأ في تجميع "لا يمكن".
القائمة 10: خطأ في التجميع لـ "لا يمكن أن يكون beappliedto"
private static void testoverloading (int [] i) {system.out.println ("a") ؛} main public static void main (string [] args) {testOverloading (1 ، 2 ، 3) ؛ // compilation error}}لهذا السبب ، لا يمكن اعتماد طريقة المكالمات الموجزة هذه مباشرة عند استدعاء طرق التي تدعم فقط لف المعلمات الفعلية مع المصفوفات (على سبيل المثال ، تلك التي تركت من تصميمات مكتبة الطرف الثالث لـ J2Se1.5).
إذا لم تتمكن من تعديل الفئة الأصلية وإضافة إصدار متغير من عدد المعلمات إلى الطريقة التي سيتم استدعاؤها ، وتريد تبني طريقة الاتصال هذه الموجزة ، يمكنك استخدام طرق إعادة الإعمار لـ "IntroduceForeGhothod" و "PromiseelOcalextension" لتقريب الغرض.
7. عندما يواجه عدد متغير من الوسائط عام
تمت إضافة آلية "عامة" جديدة إلى J2Se1.5 ، والتي يمكن أن تعرض نوعًا ما في ظل ظروف معينة. على سبيل المثال ، عند كتابة فصل ، يمكن تمثيل نوع المعلمات الرسمية للطريقة بمعرف (مثل T). بالنسبة إلى نوع هذا المعرف الذي يمثله هذا المعرف ، يتم تحديده عند إنشاء مثيل لهذه الفئة. يمكن استخدام هذه الآلية لتوفير المزيد من إعادة استخدام التعليمات البرمجية وفحص نوع الترجمة الأكثر صرامة.
ومع ذلك ، لا يمكن استخدام الآلية العامة مع أرقام متغيرة من المعلمات الرسمية. إذا تم تمثيل نوع المعلمة الرسمي الذي يطابق وسيطة غير مؤكدة بواسطة معرف ، فسيقدم برنامج التحويل البرمجي خطأ "GenericArraycreation".
القائمة 11: عندما يلتقي Varargs
private static void testvarargs (t ... args) {// error error}سبب هذه الظاهرة هو قيد متأصل للآلية العامة في J2Se1.5 - لا يمكن إنشاء مثيل من هذا النوع مع النوع الذي يمثله معرف. قبل ظهور إصدار Java الذي يدعم بدون هذا القيد ، لم يكن هناك حل جيد لهذه المشكلة.
ومع ذلك ، فإن ممارسة "التفاف مع المصفوفات" التقليدية لا تخضع لهذا القيد.
قائمة 12: حلول قابلة للتجميع
private static void testvarargs (t [] args) {for (int i = 0 ؛ i <args.length ؛ i ++) {system.out.println (args [i]) ؛ }}8. قضايا الاختيار في التحميل الزائد
تدعم Java آليات "التحميل الزائد" ، مما يسمح بالعديد من الطرق المختلفة في نفس الفئة أن تحتوي على قوائم فقط من المعلمات الرسمية. بعد ذلك ، يحدد المترجم الطريقة التي يجب تنفيذها بناءً على المعلمات الفعلية في وقت الاتصال.
تعتمد الخيارات التقليدية بشكل أساسي على مبدأ "الأشخاص المميزين المفضل". يعتمد تخصص الطريقة على عدد الشروط التي يجب الوفاء بها حتى يتم تشغيلها بسلاسة. كلما زاد عدد الشروط التي تحتاجها ، زادت خصوصية ذلك.
بعد إدخال آلية Varargs ، لا يزال هذا المبدأ ينطبق ، ولكن يتم إثراء القضايا التي يجب مراعاتها - تقليديًا ، من بين الإصدارات المختلفة من الطريقة الزائدة ، فقط أولئك الذين تكون معلماتهم المورفولوجية والمعلمات الحقيقية هي نفسها تمامًا لمزيد من الدراسة. ومع ذلك ، بعد إدخال آلية Varargs ، من الممكن مطابقة كلا الإصدارين ، ولا يوجد فرق في الجوانب الأخرى ، فقط أن معلمة حقيقية واحدة لها رقم ثابت والمعلمة الحقيقية الأخرى لها رقم متغير.
في هذه الحالة ، يتمثل قاعدة التحديد المستخدمة في أن "الإصدار الذي يحتوي على عدد ثابت من المعلمات الحقيقية له الأسبقية على الإصدار مع عدد متغير من المعلمات الحقيقية".
القائمة 13: تفضل الإصدارات ذات العدد الثابت من المعلمات الحقيقية
إذا كان ، في عرض المترجم ، طرق متعددة لها نفس الأولوية ، فسيتم تعليقها في حالة لا يمكنها الاختيار حول الطريقة التي يمكن الاتصال بها. في هذه الحالة ، سيؤدي ذلك إلى إنشاء خطأ في تجميع "المرجعية المسمى اسم الطريقة iSambiguous" وانتظر بصبر لبعض التعديلات لتجنب وصول رمز المصدر الجديد المربك.
بعد إدخال آلية Varargs ، زاد هذا الموقف الذي قد يؤدي إلى الارتباك أكثر من ذلك بقليل. على سبيل المثال ، قد يكون هناك نسخان يمكن أن يتطابقان ، وهو ما هو بالضبط في جوانب أخرى ، ويحدث كلا الصراعين مع أرقام متغيرة من المعلمات الحقيقية.
OverloadingsMplea {public static void main (string [] args) {testoverloading (1) ؛ // print out ontestoverloading (1 ، 2) ؛ // print Out btestoverloading (1 ، 2 ، 3) ؛ j) {system.out.println ("b") ؛} private static void testoverloading (int i ، int ... more) {system.out.println ("c") ؛}}إذا كان ، في عرض المترجم ، طرق متعددة لها نفس الأولوية ، فسيتم تعليقها في حالة لا يمكنها الاختيار حول الطريقة التي يمكن الاتصال بها. في هذه الحالة ، سيؤدي ذلك إلى إنشاء خطأ في تجميع "المرجعية المسمى اسم الطريقة iSambiguous" وانتظر بصبر لبعض التعديلات لتجنب وصول رمز المصدر الجديد المربك.
بعد إدخال آلية Varargs ، زاد هذا الموقف الذي قد يؤدي إلى الارتباك أكثر من ذلك بقليل. على سبيل المثال ، قد يكون هناك نسخان يمكن أن يتطابقان ، وهو ما هو بالضبط في جوانب أخرى ، ويحدث كلا الصراعين مع أرقام متغيرة من المعلمات الحقيقية.
القائمة 14: بغض النظر عن ذلك ، من الصعب على المترجم أن يكون
الفئة العامة الزائدة عن الحملات العامة {public static void main (string [] args) {testOverloading (1 ، 2 ، 3) ؛ // error error} private static void testoverload (Object ... args) {}}بالإضافة إلى ذلك ، نظرًا لوجود آلية "Autoboxing/Auto-inboxing" في J2Se1.5 ، فمن الممكن أن يتطابق كلا الإصدارين ، وعدد المعلمات الحقيقية متغيرة ، والجوانب الأخرى هي نفسها تمامًا. إنه مجرد معلمة حقيقية مقبولة هي النوع الأساسي ، في حين أن المعلمة الحقيقية الأخرى المقبولة هي الصراع بين فئة الحزمة.
القائمة 15: قضايا جديدة من Autoboxing/Auto-unboxing
OverloadingsMplesamplec {public static void main (string [] args) {/* error error*/testoverloading (1 ، 2) ؛/* أو error error*/testoverloading (integer new (1) ، integer new (2)) ؛}9. ملخص
بالمقارنة مع طريقة "ملفوفة بالمصفوفات" ، فإن الطريقة الحقيقية مع المعلمات الحقيقية المتغيرة هي أبسط ولها معاني أوضح عند الاتصال. ومع ذلك ، فإن هذه الآلية لها حدود خاصة بها وليست حلاً مثاليًا.
ما سبق هو كل التفسير المفصل لرمز المعلمة الطول المتغير في Java ، وآمل أن يكون مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى هذا الموقع:
شرح مفصل للمعلمات الضمنية وحالات المعلمة عرض في جافا
تنفيذ برمجة Java للفرز السريع والرمز التفصيلي التفصيلي
فك تشفير Java decryption والتوقيع الرقمي مثال رمز كامل
إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها. شكرا لك يا أصدقائك لدعمكم لهذا الموقع!