JavaRush /مدونة جافا /Random-AR /أنواع البيانات المرجعية في جافا

أنواع البيانات المرجعية في جافا

نشرت في المجموعة
بدون فهم بناء جملة Java، من المستحيل أن تصبح مطورًا جادًا، لذلك نواصل اليوم تعلم بناء الجملة. تحدثنا في أحد المقالات السابقة عن المتغيرات البدائية، ولكن بما أن هناك نوعين من المتغيرات، فسنتحدث اليوم عن النوع الثاني - الأنواع المرجعية في Java. إذا ما هو؟ لماذا هناك حاجة إلى أنواع البيانات المرجعية في Java؟ أنواع البيانات المرجعية في جافا - 1لنتخيل أن لدينا كائنًا تلفزيونيًا يتمتع ببعض الخصائص، مثل رقم القناة ومستوى الصوت والعلم:
public class TV {
   int numberOfChannel;
   int soundVolume;
   boolean isOn;
}
كيف يمكن لنوع بسيط مثل intتخزين هذه البيانات؟ دعونا نتذكر: متغير واحد intهو 4 بايت. ولكن يوجد بالداخل متغيران (4 بايت + 4 بايت) من نفس النوع، وأيضًا boolean(+1 بايت)... الإجمالي - من 4 إلى 9، ولكن كقاعدة عامة، يتم تخزين المزيد من المعلومات في الكائن. ما يجب القيام به؟ لا يمكنك وضع كائن في متغير. في هذه المرحلة من قصتنا، تظهر المتغيرات المرجعية. تقوم المتغيرات المرجعية بتخزين عنوان موقع الذاكرة الذي يوجد به كائن معين. أي أنها "بطاقة عمل" تحتوي على عنوان يمكننا من خلاله العثور على كائننا في الذاكرة المشتركة وإجراء بعض المعالجات به. الإشارة إلى أي كائن في Java هي متغير مرجعي. هذا ما سيبدو عليه كائننا التلفزيوني:
TV telly = new TV();
قمنا بتعيين متغير من النوع TV باسم tellyرابط للكائن الذي تم إنشاؤه من النوع TV. أي أن JVM يخصص الذاكرة على الكومة لكائن التلفزيون، ويقوم بإنشائه والعنوان لموقعه في الذاكرة، ويضعه في المتغير tellyالذي يتم تخزينه على المكدس. يمكنك قراءة المزيد عن الذاكرة، أي المكدس والكثير من المعلومات المفيدة الأخرى، في هذه المحاضرة . متغير من النوع TV وكائن من النوع TV، هل لاحظت؟ وهذا ليس بدون سبب: يجب أن يكون للكائنات من نوع معين متغيرات مقابلة من نفس النوع (لا نحسب تطبيقات الوراثة والواجهة، لكننا الآن لا نأخذ ذلك في الاعتبار). ففي نهاية المطاف، لن نقوم بسكب الحساء في أكواب، أليس كذلك؟ اتضح أن كائننا هو جهاز تلفزيون، والمتغير المرجعي له يشبه لوحة التحكم. باستخدام جهاز التحكم عن بعد هذا يمكننا التفاعل مع كائننا وبياناته. على سبيل المثال، قم بتعيين خصائص جهاز التلفزيون الخاص بنا:
telly.isOn = true;
telly.numberOfChannel = 53;
telly.soundVolume = 20;
استخدمنا هنا العامل النقطي .للوصول إلى العناصر الداخلية للكائن الذي يشير إليه المتغير والبدء في استخدامها. على سبيل المثال، في السطر الأول قلنا للمتغير telly: "أعطنا متغيرًا داخليًا isOnللكائن الذي تشير إليه واضبطه على صحيح" (قم بتشغيل التلفزيون لنا).

إعادة تعريف المتغيرات المرجعية

لنفترض أن لدينا متغيرين من نوع مرجعي والكائنات التي يشيرون إليها:
TV firstTV = new TV();
TV secondTV = new TV();
إذا كتبنا:
firstTV = secondTV;
هذا يعني أننا قمنا بتعيين المتغير الأول كقيمة نسخة من العنوان (قيمة بتات العنوان) للكائن الثاني، والآن يشير كلا المتغيرين إلى الكائن الثاني (وبعبارة أخرى، جهازي تحكم عن بعد لنفس الشيء تلفزيون). وفي الوقت نفسه، تم ترك الكائن الأول بدون متغير يشير إليه. ونتيجة لذلك، لدينا كائن لا يمكن الوصول إليه، لأن المتغير كان بمثابة خيط شرطي له، والذي بدونه يتحول إلى قمامة، ويكمن فقط في الذاكرة ويشغل مساحة. سيتم بعد ذلك إتلاف هذا الكائن من الذاكرة بواسطة أداة تجميع مجمعي البيانات المهملة . أنواع البيانات المرجعية في جافا - 2يمكنك قطع خيط الاتصال بكائن دون رابط آخر:
secondTV = null;
ونتيجة لذلك، سيكون هناك رابط واحد فقط للكائن - firstTVولن secondTVيشير بعد الآن إلى أي شخص (وهذا لا يمنعنا من تعيين رابط لكائن ما مثل التلفزيون في المستقبل).

فئة السلسلة

بشكل منفصل، أود أن أذكر فئة السلسلة . هذه فئة أساسية مصممة لتخزين البيانات المخزنة كسلسلة والعمل معها. مثال:
String text = new String("This TV is very loud");
قمنا هنا بتمرير سلسلة ليتم تخزينها في مُنشئ الكائن. لكن لا أحد يفعل ذلك. بعد كل شيء، يمكن إنشاء سلاسل:
String text = "This TV is very loud";
أكثر ملاءمة، أليس كذلك؟ من حيث شعبية الاستخدام، Stringفهو ليس أقل شأنا من الأنواع البدائية، لكنه لا يزال فئة، والمتغير الذي يشير إليه ليس نوعا بدائيا، ولكنه نوع مرجعي. لدينا Stringهذه القدرة الرائعة على ربط السلاسل:
String text = "This TV" + " is very loud";
ونتيجة لذلك، سوف نحصل على النص مرة أخرى: This TV is very loudحيث سيتم دمج السطرين في كل واحد، وسوف يشير المتغير إلى هذا النص الكامل. فارق بسيط مهم هو أن Stringهذه فئة غير قابلة للتغيير. ماذا يعني ذلك؟ لنأخذ هذا المثال:
String text = "This TV";
text = text + " is very loud";
يبدو أن كل شيء بسيط: نعلن عن متغير ونعطيه قيمة. في السطر التالي نقوم بتغييره. لكننا لا نتغير حقاً. نظرًا لأن هذه فئة غير قابلة للتغيير، فلن يتم تغيير القيمة الأولية في السطر الثاني، ولكن يتم إنشاء قيمة جديدة، والتي تتكون بدورها من القيمة الأولى + " is very loud".

الثوابت المرجعية

في المقال عن الأنواع البدائية، تطرقنا إلى موضوع الثوابت. كيف سيتصرف المتغير المرجعي عندما نعلن أنه نهائي ؟
final TV telly = new TV();
قد تعتقد أن هذا سيجعل الكائن غير قابل للتغيير. ولكن لا، هذا ليس صحيحا. أنواع البيانات المرجعية في جافا - 3سيتم ربط المتغير المرجعي مع المُعدِّل finalبكائن معين دون القدرة على إلغاء ربطه بأي شكل من الأشكال (إعادة تعريفه أو مساواته بـ null). أي أنه بعد تحديد قيمة هذا المتغير، يتم كتابة كود مثل:
telly = new TV();
أو
telly = null;
سوف يسبب خطأ في التجميع. أي finalأنه يعمل فقط على الرابط، وليس له أي تأثير على الكائن نفسه. إذا جعلناه قابلاً للتغيير في البداية، فيمكننا تغيير حالته الداخلية دون أي مشاكل:
telly.soundVolume = 30;
في بعض الأحيان، يتم تعيين المتغيرات على أنها نهائية حتى في وسيطات الطريقة!
public void enableTV (final TV telly){
   telly.isOn = true;
}
يتم ذلك بحيث لا يمكن تجاوز هذه الوسائط أثناء عملية كتابة الطريقة، وبالتالي خلق ارتباك أقل. ماذا لو أشرنا إلى finalمتغير مرجعي يشير إلى كائن غير قابل للتغيير؟ على سبيل المثال String:
final String PASSWORD = "password";
ونتيجة لذلك، سنحصل على ثابت، تناظري للثوابت من النوع البدائي، لأنه هنا لا يمكننا إعادة تعريف المرجع ولا تغيير الحالة الداخلية للكائن (البيانات الداخلية).

دعونا نلخص ذلك

  1. بينما تقوم المتغيرات البسيطة بتخزين بتات القيمة، تقوم المتغيرات المرجعية بتخزين البتات التي تمثل كيفية استرجاع الكائن.
  2. يتم الإعلان عن مراجع الكائنات لنوع واحد فقط من الكائنات.
  3. أي فئة في Java هي نوع مرجعي.
  4. القيمة الافتراضية لأي متغير مرجعي في Java هي null.
  5. Stringهو مثال قياسي لنوع مرجعي. هذه الفئة أيضًا غير قابلة للتغيير.
  6. ترتبط المتغيرات المرجعية مع المُعدِّل finalبكائن واحد فقط دون إمكانية إعادة التعريف.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION