Home برمجة جافا جافا دائماً Passing by Value
جافا دائماً Passing by Value

جافا دائماً Passing by Value

335
2

من المفاهيم الأساسية في مفهوم الدوال Functions/Methods في لغات البرمجة هو تمرير الوسائط Parameter Passing ، وبشكل عام هناك طريقتين للتمرير المعاملات الأولى هي التمرير بالقيمة Pass by Value والثانية هي Pass by Reference  .

عند استخدام النوع الأول Pass by Value سوف يتم نسخ القيمة من المتغير أو الكائن المرسل الى المعامل الموجود في الدالة التي تم استدعائها ، وأي تغيير يتم اجرائه على هذا المعامل فلن يتأثر المتغير الأول والسبب أنه تم تمرير القيمة فقط .

أما عند استخدام النوع الثاني Pass by Reference فسوف يتم ارسال عنوان Pointer/Reference المتغير أو الكائن الى المعامل الموجود في الدالة ، وسوف يكون هذا المعامل يؤشر للمتغير أو الكائن وبالتالي أي تغيير يتم اجرائه على المعامل سوف يتغير المتغير أو الكائن تبعا لذلك ، لأنهم الإثنين يؤشران لنفس المنطقة في الذاكرة .

تقريبا أي مبرمج ولو حتى مبتدئ يعرف هذا الكلام بشكل جيد ، ولكن هناك فهم غير دقيق misconception خاصه عند خلط الحديث بين التمرير في لغه مثل سي/سي++ مع الجافا ، ومصدر هذه المشكلة هو أنه في لغه سي++ يمكنك تنشيء كائن object يوجد في المكدس Stack أو يمكنك أنشاء الكائن في الHeap وتتعامل معه من خلال Pointer أو Reference .  بينما في الجافا دائما الكائنات تتواجد في ال Heap وتتعامل معها من خلال الReference.

مثال :

بالنظر الى المثال السابق سنجد في مثال سي++ أن st يسمى كائن Object وst2  يسمى مؤشر لكائن Pointer to Object ، بينما في مثال الجافا فإن الst3  يسمى Reference to Object حيث أن الكائن موجود في الذاكرة Heap و st3 هو مجرد مؤشر لتلك المنطقة .

نأتي الأن لموضوع التمرير Passing ، ففي لغات سي\سي++ فهي تسمح بأن يتم ارسال المتغير أو الكائن من خلال طريقتين Value or Reference  ،  بينما في الجافا يتم دائما الإرسال بالقيمة سواء لمتغير أو لReference to Object  .

بالتالي وبسبب هذا النوع من التمرير فإنه:

  1. لا يمكن أن تغير الدالة قيمة أي primitive مرسل .
  2. تستطيع الدالة تغيير أحد المتغيرات الموجودة في الكائن المرسل (أقصد المؤشر للكائن المرسل) .
  3. لا تستطيع الدالة تغيير المؤشر المرسل وجعله يؤشر لكائن أخر .

الأمثله التالية خير برهان للنقاط أعلاه ،، والمثال الأول سوف يثبت صحة النقطة الأولى

1) لا يمكن أن تغير الدالة قيمة أي primitive مرسل :

وكما هو واضح من المخرج التالي :

 passing_1

فإن قيمة x لم تتغير بعد استدعاء دالة التغيير ، وهكذا تم اثبات النقطة الأولى .

2) تستطيع الدالة تغيير أحد المتغيرات الموجودة في الكائن المرسل (أقصد المؤشر للكائن المرسل)

وكما هو واضح من المخرج التالي:
passing_2

3) لا تستطيع الدالة تغيير المؤشر المرسل وجعله يؤشر لكائن أخر (مصدر الخلل) .

وكما هو واضح من المخرج التالي :

 passing_3

فأنه لا يمكن عمل swap بين المتغيرات والسبب أننا من الأساس لا يمكن تغيير قيمة أي Primitive type (النقطة الأولى) ، بالنسبة للSwap الثانية بين الكائنات فالذي حصل هو أنه تم تمرير عنواين الكائنات بالقيمة pass by value للدالة swapReference ، وبعدها تم تغيير قيم المعاملات وجعل كل منها يؤشر للأخر ولكن هذا لن يؤثر في المؤشرات في الدالة main والسبب أنه تم ارساله العنواين بالقيمة .

ومن هنا كانت العباره :
Java Always passing by Value

(335)

وجدي عصام مهندس برمجيات مهتم بعلوم الحاسب وبالأخص مجال الخوارزميات وهندسة البرمجيات وحماية التطبيقات،

Comment(2)

  1. أشكرك أستاذ عصام، حقيقة لم أكن أعلم ذلك قبل قراءة الدرس، أشكرك على المقال الواضح والمعلومة الجديدة

LEAVE YOUR COMMENT

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

مشاركة