استدعاء الطريقة من قبل مصطلح علوم الكمبيوتر القياسية. يتم تقسيم مكالمات الطريقة إلى مكالمات القيمة (الاتصال بالرجوع) والمكالمات المرجعية (استدعاء حسب القيمة) وفقًا لموقف تمرير المعلمة. هناك العديد من التعريفات لهذين النوعين من المكالمات في العالم. القول الأكثر شيوعًا هو أن القيمة هي استدعاء القيمة ، والعنوان هو المكالمة المرجعية. هذا في الواقع غير مناسب للغاية. يمكن أن تذكرنا هذه العبارات بسهولة بأن معلمة كائن Java هي مكالمة مرجعية. في الواقع ، لا يزال تمرير معلمة كائن Java عبارة عن مكالمة قيمة.
دعنا نستخدم أولاً قطعة من التعليمات البرمجية لتأكيد سبب تمرير معلمة كائن Java.
موظف الفئة العامة {اسم السلسلة العامة = null ؛ الموظف العام (سلسلة n) {this.name = n ؛ } // مبادلة اثنين من كائنات الموظف مبادلة الفراغ الثابتة العامة (الموظف E1 ، الموظف e2) {الموظف temp = e1 ؛ e1 = e2 ؛ E2 = درجة الحرارة ؛ System.out.println (e1.name+""+e2.name) ؛ // نتيجة طباعة: Li Si Zhang San} // الوظيفة الرئيسية الفراغ الثابتة الرئيسية (String [] args) {موظف عامل = موظف جديد ("Zhang San") ؛ مدير الموظف = موظف جديد ("Li Si") ؛ مبادلة (عامل ، مدير) ؛ system.out.println (worker.name+""+manager.name) ؛ // لا تزال نتيجة الطباعة: Zhang San Li Si}}}النتيجة أعلاه مخيبة للآمال للغاية. على الرغم من أن محتويات كائنات المعلمة الرسمية تم تبادل E1 و E2 ، إلا أن عامل وكائنات المعلمة الفعلية لم يتبادلوا المحتويات. السبب الأكثر أهمية هنا هو أن المعلمات الرسمية E1 و E2 هي نسخ العنوان لعامل ومدير المعلمات الفعلية.
كما نعلم جميعًا ، في Java ، تمثل أسماء متغيرات الكائن بالفعل عنوان الكائن في الكومة (يسمى المصطلح المهني مرجع الكائن). عندما يتم استدعاء طريقة Java ، تمرر المعلمات مرجعًا إلى الكائن. الأهم من ذلك ، عناوين الذاكرة التي تشغلها المعلمات الرسمية والمعلمات الفعلية ليست هي نفسها. المحتويات في المعلمات الرسمية هي مجرد نسخة من مرجع الكائن المخزن في المعلمات الفعلية.
إذا كان لديك بعض الفهم للمنطقة المتغيرة المحلية في مكدس Java في إدارة ذاكرة JVM (انظر "Java Virtual Machine Architecture") ، فسوف تفهم الجملة أعلاه بشكل جيد للغاية. عندما تقوم JVM بتشغيل البرنامج أعلاه ، فإن تشغيل الطريقة الرئيسية وسيقوم طريقة المبادلة بدفع مساحتين للذاكرة تسمى إطارات المكدس في مكدس Java. هناك قطعة من الذاكرة تسمى المنطقة المتغيرة المحلية في إطار المكدس الرئيسي لتخزين المراجع إلى عامل ومدير كائنات المعلمة الفعلية. تخزن المنطقة المتغيرة المحلية في إطار مكدس المبادلة إشارات إلى كائنات المعلمة الرسمية E1 و E2. على الرغم من أن القيم المرجعية لـ E1 و E2 هي نفس القيم العامل والمدير ، إلا أنها تشغل مساحة مختلفة من الذاكرة. عند تبادل المراجع بين E1 و E2 ، يوضح الشكل أدناه بوضوح أنه لن يؤثر على القيم المرجعية للعامل والمدير على الإطلاق.
لا يزال تمرير معلمة كائن Java مكالمة قيمة على الرغم من تمرير العنوان (المرجع). حان الوقت لإعطاء المكالمة المرجعية والقيمة استدعاء تعريف دقيق.
استدعاء بالقيمة: أثناء عملية تمرير المعلمة ، تشغل المعلمات الرسمية والمعلمات الفعلية مساحين مختلفين تمامًا للذاكرة. المحتوى المخزّن بواسطة المعلمة الرسمية هو نسخة من المحتوى المخزّن بواسطة المعلمة الفعلية. في الواقع ، فإن تمرير كائنات Java يلبي هذا التعريف ، باستثناء أن المحتوى المخزّن بواسطة المعلمات الرسمية والمعلمات الفعلية ليس القيمة المتغيرة بالمعنى التقليدي ، ولكن عنوان المتغير. حسنًا ، فكر مرة أخرى: أليس عنوان متغير أيضًا قيمة؟
اتصل بالرجوع: أثناء عملية تمرير المعلمة ، تكون المعلمات الرسمية والمعلمات الفعلية نفس مساحة الذاكرة تمامًا ، ولا يتم تمييز الاثنين عن بعضها البعض. في الواقع ، أسماء المعلمات الرسمية وأسماء المعلمات الفعلية هي مجرد رموز مختلفة في البرمجة. أثناء تشغيل البرنامج ، فإن المساحة المخزنة في الذاكرة هي أهم شيء. لا تشير أسماء المتغيرات المختلفة إلى مساحة تخزين الذاكرة المشغولة بشكل مختلف.
بشكل عام ، فإن أساسيات المكالمتين ليست ما إذا كانت القيمة أو العنوان قد تم تمريرها (بعد كل شيء ، العنوان هو أيضًا قيمة) ، ولكن ما إذا كانت المعلمات الرسمية والمعلمات الفعلية تشغل نفس مساحة الذاكرة. في الواقع ، فإن معلمة المؤشر التي تمر في C/C ++ هي أيضًا استدعاء قيمة. إذا كنت لا تصدق ذلك ، جرب رمز C التالي!
#include <stdio.h> void swap (int *a1 ، int *b1) {int *t = a1 ؛ A1 = B1 ؛ B1 = T ؛ } int main () {int x1 = 100 ؛ int x2 = 200 ؛ int *a = & x1 ؛ int *b = & x2 ؛ printf ("٪ d ٪ d/n" ،*a ،*b) ؛ مبادلة (أ ، ب) ؛ printf ("٪ d ٪ d/n" ،*a ،*b) ؛ العودة 0 ؛ }لكن C/C ++ لديها مكالمات مرجعية ، وهي طريقة إعلان متغيرة تسمى المرجع int a ؛ int & ra = a ؛ حيث RA هو الاسم المستعار ل. لا يوجد فرق بين الاثنين في الذاكرة ويشغلون نفس مساحة الذاكرة. تمرير المعلمات من خلال المرجع (الاستعداد) يتماشى مع خصائص المكالمات المرجعية. يمكنك تجربة نتائج تشغيل مبادلة void (int & a1 ، int & b1) ؛
من خلال هذه المقالة ، يجب أن تعرف ما إذا كانت معلمات طريقة Java تسمى المرجع أو القيمة.