الفرق بين متغيرات الأعضاء الثابتة ومتغيرات الأعضاء غير الثابتة
خذ المثال التالي كمثال
package cn.galc.test;public class Cat { /** * متغير العضو الثابت*/ معرف سلسلة خاص = sid; } public void info() { System.out.println("اسمي هو " + name + ",NO." + id); } public static void main(String[] args) { Cat.sid = 100 قطة mimi = قطة جديدة("mimi");فهم عملية تنفيذ البرنامج بأكمله من خلال رسم مخططات تحليل الذاكرة
عند تنفيذ الجملة الأولى من البرنامج: Cat.sid = 100;، sid هنا هو متغير عضو ثابت، ويتم تخزين المتغير الثابت في منطقة البيانات (قطاع البيانات)، لذا قم أولاً بتخصيص مساحة صغيرة sid في منطقة البيانات. بعد تنفيذ الجملة، يحتوي sid على قيمة 100.
مخطط تخطيط الذاكرة في هذا الوقت هو كما يلي:
بعد ذلك ينفذ البرنامج:
القطة ميمي = القطة الجديدة("ميمي");هنا يتم استدعاء طريقة المنشئ Cat (اسم السلسلة) لفئة Cat. يتم تعريف طريقة المنشئ على النحو التالي:
Cat (اسم السلسلة) { this.name = name=sid++ }; عند الاتصال، قم أولاً بتخصيص قطعة صغيرة من الذاكرة mm في ذاكرة المكدس، والتي تحتوي على عنوان كائن مثيل فئة Cat في ذاكرة الكومة mm هو الكائن المرجعي لكائن فئة Cat في ذاكرة الكومة. يعلن هذا المنشئ عن متغير معلمة رسمي من نوع السلسلة، لذلك يتم تمرير "mimi" إلى المنشئ كمعلمة فعلية نظرًا لتخصيص ثابت السلسلة وتخزينه في منطقة البيانات، توجد قطعة صغيرة إضافية من الذاكرة في منطقة البيانات تستخدم لتخزين السلسلة "mimi". يظهر توزيع الذاكرة في هذا الوقت في الشكل أدناه:
عند استدعاء المنشئ، قم أولاً بتخصيص مساحة صغيرة في ذاكرة المكدس لاسم المعلمة الرسمية، ثم قم بتمرير السلسلة "mimi" كمعلمة فعلية للتسمية. السلسلة هي أيضًا نوع مرجعي، باستثناء تلك الأربعة والثمانية أنواع البيانات الأساسية، وجميع الأنواع الأخرى هي أنواع مرجعية، لذلك يمكن اعتبار أن السلسلة هي أيضًا كائن. لذا فإن هذا يعادل تمرير مرجع كائن "mimi" إلى الاسم، لذا يشير الاسم الآن إلى "mimi". لذا فإن تخطيط الذاكرة في هذا الوقت كما هو موضح أدناه:
بعد ذلك، قم بتنفيذ التعليمات البرمجية في نص المنشئ:
this.name=name;
يشير هذا هنا إلى الكائن الحالي، والذي يشير إلى القطة الموجودة في ذاكرة الكومة. هنا، يتم تمرير القيمة الموجودة في الاسم في المكدس إلى سمة الاسم لكائن القط في ذاكرة الكومة، لذلك في هذا الوقت يمكن أيضًا العثور على القيمة الموجودة في الاسم في كائن السلسلة "mimi" الموجود في منطقة البيانات في هذا الوقت، يعد هذا الاسم أيضًا كائنًا مرجعيًا لكائن السلسلة "mimi". من خلال قيمة السمة الخاصة به، يمكن العثور على كائن السلسلة "mimi" الموجود في منطقة البيانات. يظهر توزيع الذاكرة في هذا الوقت في الشكل أدناه:
بعد ذلك، قم بتنفيذ سطر آخر من التعليمات البرمجية في نص الطريقة:
معرف=sid++;
هنا، يتم تمرير قيمة sid إلى id، وبالتالي فإن قيمة id هي 100. وبعد تمرير sid، أضف 1. في هذا الوقت، يصبح sid 101. يظهر تخطيط الذاكرة في هذا الوقت في الشكل أدناه.
في هذه المرحلة، يتم استدعاء أسلوب المنشئ، وستختفي كل مساحة الذاكرة التي تشغلها المتغيرات المحلية المخصصة لأسلوب المنشئ، وبالتالي تختفي ذاكرة الاسم الموجودة في مساحة المكدس. يختفي أيضًا المرجع إلى كائن السلسلة "mimi" في منطقة البيانات في ذاكرة المكدس. في هذا الوقت، يبقى فقط المرجع إلى كائن السلسلة "mimi" في ذاكرة الكومة. تخطيط الذاكرة في هذا الوقت كما هو موضح أدناه:
التنفيذ التالي:
كات بيبي = قطة جديدة("بيبي"); فيما يلي الاستدعاء الثاني لطريقة المُنشئ Cat(). عملية الاستدعاء بأكملها هي نفس المرة الأولى، بعد اكتمال الاستدعاء، يكون تخطيط الذاكرة في هذا الوقت كما هو موضح في الشكل أدناه:
تتم طباعة السطرين الأخيرين من التعليمات البرمجية عن طريق استدعاء طريقة المعلومات () وتكون نتائج الطباعة كما يلي:
من خلال هذا البرنامج يمكننا أن نرى دور هذا العضو الثابت المتغير sid والذي يمكن عده. عندما تظهر قطة جديدة، أعطها رقمًا. دعها تضيف 1 بنفسها.
بعد تنفيذ البرنامج، سيكون التخطيط بأكمله في الذاكرة كما هو موضح في الشكل أعلاه. يستمر حتى اللحظة التي تسبق اكتمال استدعاء الطريقة الرئيسية.
هنا، يتم استدعاء الأسلوب المنشئ Cat (اسم السلسلة) لإنشاء قطتين. أولاً، يتم تخصيص مسافتين صغيرتين، mimi وpipi، في ذاكرة المكدس، والتي تحتوي على العناوين التي يمكن العثور على القطتين فيها mimi وpipi إلى العناوين الموجودة في ذاكرة الكومة، اقتباسات قطتان. تعلن طريقة البناء هنا عن متغير من نوع السلسلة، ويتم تخصيص ثابت السلسلة في منطقة البيانات، لذلك سيتم تخزين السلاسل التي تم تمريرها mimi وpipi في منطقة البيانات. لذلك، يتم تخصيص كتلتين صغيرتين من الذاكرة لتخزين السلاسل mimi وpipi، والتي تحتوي على السلاسل "mimi" و"pipi" أيضًا، بالإضافة إلى أنواع البيانات الأساسية الأربعة والثمانية كافة أنواع البيانات هي أنواع مرجعية. لذلك يمكنك التفكير في السلسلة ككائن.
إليك قطتان جديدتان لهما سمات المعرف والاسم الخاصة بهما، لذا فإن المعرف والاسم هنا عبارة عن متغيرات أعضاء غير ثابتة، أي أنه لا يوجد تعديل ثابت. لذلك في كل مرة يتم إنشاء قطة جديدة، يكون لهذه القطة الجديدة معرف واسم خاص بها، أي أن معرف واسم متغيرات العضو غير الثابتة لهما نسخ منفصلة لكل كائن. ولكن بالنسبة لمتغيرات الأعضاء الثابتة، هناك نسخة واحدة فقط، بغض النظر عن عدد الكائنات الجديدة، حتى لو لم تكن هناك كائنات جديدة، ستحتفظ متغيرات الأعضاء الثابتة بنسخة واحدة في منطقة البيانات. مثل sid هنا، يتم تخزين sid في منطقة البيانات، بغض النظر عن عدد القطط الجديدة الموجودة في ذاكرة الكومة، هناك نسخة واحدة فقط من sid، ويتم الاحتفاظ بنسخة واحدة فقط في منطقة البيانات.
تنتمي متغيرات الأعضاء الثابتة إلى الفئة بأكملها، وليس إلى كائن معين. فكيف يمكن الوصول إلى قيمة متغير العضو الثابت هذا؟ بادئ ذي بدء، يمكن لأي كائن الوصول إلى هذه القيمة الثابتة، وعند الوصول، فإنه يصل إلى نفس الذاكرة. النقطة الثانية هي أنه يمكنك الوصول إلى هذه القيمة الثابتة حتى في حالة عدم وجود كائن. يمكنك الوصول إلى هذه القيمة الثابتة من خلال "اسم متغير العضو الثابت"، لذلك سترى في المستقبل اسم فئة معينًا بالإضافة إلى "." متبوعًا إذا كان هناك شيء واحد، فيجب أن يكون الشيء التالي ثابتًا، مثل "System.out". هنا، يتم الوصول إلى هذا الخارج من خلال اسم الفئة (فئة النظام) بالإضافة إلى "."، لذلك يجب أن يكون هذا الخارج ثابتًا.
إذا تم تعريف عضو فئة بأنه ثابت، فيمكن الوصول إليه قبل إنشاء أي كائن من الفئة دون الحاجة إلى الرجوع إلى أي كائن. المثال الأكثر شيوعًا للعضو الثابت هو main(). لأنه يجب استدعاء main() عند بدء تنفيذ البرنامج، يتم تعريفه بأنه ثابت.
المتغيرات المعلنة ثابتة هي في الأساس متغيرات عالمية. عندما يتم الإعلان عن كائن، لا يتم إنشاء نسخة من المتغير الثابت، ولكن جميع متغيرات مثيلات الفئة تشترك في نفس المتغير الثابت. على سبيل المثال: قم بتعريف عدد متغير ثابت كعدد مثيلات الفئة الجديدة. الأساليب المعلن عنها ثابتة لها القيود التالية:
(1) يمكنهم فقط استدعاء الطرق الثابتة الأخرى.
(2) يمكنهم فقط الوصول إلى البيانات الثابتة.
(٣) لا يجوز لهم الرجوع إلى هذا أو السوبر بأي حال من الأحوال.
إذا كنت بحاجة إلى تهيئة المتغيرات الثابتة الخاصة بك من خلال الحساب، فيمكنك إعلان كتلة ثابتة. يتم تنفيذ الكتلة الثابتة مرة واحدة فقط عند تحميل الفصل. يظهر المثال أدناه
يحتوي الفصل على طريقة ثابتة وبعض المتغيرات الثابتة وكتلة تهيئة ثابتة: public class UserStatic { static int a = 3; static void meth(int x) { System.out.println("x = " + x); System.out.println("a = "+ a); System.out.println("b = " + b); تمت التهيئة."); b = a * 4; } public static void main(String args[]) { meth(42); } } بمجرد تحميل فئة UseStatic، سيتم تشغيل كافة البيانات الثابتة. أولاً، يتم تعيين a على 3، ثم يتم تنفيذ الكتلة الثابتة (طباعة رسالة)، وأخيرًا، تتم تهيئة b إلى a*4 أو 12. بعد ذلك يتم استدعاء main()، واستدعاء main() meth()، وتمرير القيمة 42 إلى x. تشير عبارات println () الثلاثة إلى متغيرين ثابتين a وb، والمتغير المحلي x.
ملاحظة: من غير القانوني الإشارة إلى أي متغيرات مثيلة بطريقة ثابتة.
هنا هو إخراج هذا البرنامج:
تمت تهيئة الكتلة الثابتة x = 42 أ = 3 ب = 12
يمكن استخدام الأساليب والمتغيرات الثابتة بشكل مستقل عن أي كائن خارج الفئة التي تم تعريفها فيها. بهذه الطريقة، يمكنك فقط إضافة عامل النقطة (.) بعد اسم الفئة. على سبيل المثال، إذا كنت ترغب في استدعاء أسلوب ثابت من خارج الفئة، يمكنك استخدام التنسيق العام التالي:
classname.method()
هنا، اسم الفئة هو اسم الفئة التي يتم فيها تعريف الطريقة الثابتة. كما ترون، هذا التنسيق مشابه لتنسيق استدعاء الأساليب غير الثابتة من خلال المتغيرات المرجعية للكائنات. يمكن الوصول إلى متغير ثابت بنفس التنسيق - اسم الفئة متبوعًا بعامل النقطة. هذه هي الطريقة التي تنفذ بها Java نسخة خاضعة للرقابة من الوظائف العامة والمتغيرات العامة.
تلخيص:
(1) لا يمكن الوصول إلى الأعضاء الثابتين عن طريق المثيلات التي تم إنشاؤها بواسطة الفئة التي يتواجدون فيها.
(2) إذا كان الأعضاء الذين لم يتم تعديلهم ثابتًا هم أعضاء كائن، فإنهم مملوكون لكل كائن.
(3) الأعضاء المعدلون بالثبات هم أعضاء فئة، ويمكن للفئة استدعائهم مباشرة وهم مشتركون بين جميع الكائنات.
Java Static: كمعدِّل، يمكن استخدامه لتعديل المتغيرات والأساليب وكتل التعليمات البرمجية (لكن يجب ألا يعدل الفئات).
(1) تعديل المتغيرات:
خاصية مشتركة بين جميع كائنات الفئة، وتسمى أيضًا متغير الفئة. وهذا مشابه للمتغيرات العامة في لغة C. تتم تهيئة متغيرات الفئة عند تحميل الفئة وتهيئتها مرة واحدة فقط. عندما يقوم أي كائن في البرنامج بتعديل متغير ثابت، فإن الكائنات الأخرى سوف ترى القيمة المعدلة. لذلك يمكن استخدام متغيرات الفئة كعدادات. بالإضافة إلى ذلك، يمكن الوصول إلى متغيرات Java Static مباشرة باستخدام اسم الفئة دون الحاجة إلى كائن.
(2) طريقة التعديل:
تسمى الوظيفة المشتركة بين جميع كائنات الفئة طريقة ثابتة. يمكن أيضًا الوصول إلى الأساليب الثابتة مباشرةً باستخدام اسم الفئة، دون الحاجة إلى كائن. ولذلك، لا يمكن الوصول مباشرة إلى المتغيرات غير الثابتة والأساليب غير الثابتة في الأساليب الثابتة، ولا يمكن أن تظهر الكلمات الأساسية مثل this أو super في الأساليب الثابتة.
(3) تعديل كتل تعليمات Java البرمجية:
استخدم ثابتًا لتعديل كتلة التعليمات البرمجية المستقلة في الفصل الدراسي، والتي تسمى كتلة التعليمات البرمجية الثابتة. يتم تنفيذ كتل التعليمات البرمجية الثابتة عند تحميل الفصل لأول مرة، ولمرة واحدة فقط. لا تحتوي كتل التعليمات البرمجية الثابتة على أسماء، لذا لا يمكن استدعاؤها بشكل صريح، ولكن يتم استدعاؤها فقط بواسطة الجهاز الظاهري عند تحميل الفصل. يتم استخدامه بشكل أساسي لإكمال بعض عمليات التهيئة.
(4) لنتحدث عن تحميل الفصل:
عندما يستخدم JVM فئة لأول مرة، فإنه سينتقل إلى المسار المحدد بواسطة مسار الفئة للعثور على ملف الرمز الثانوي المطابق للفئة، وقراءته في JVM وحفظه. وتسمى هذه العملية تحميل الفئة.
يمكن أن نرى أنه سواء كان متغيرًا أو طريقة أو كتلة تعليمات برمجية، طالما تم تعديله باستخدام ثابت، فسيكون "جاهزًا" عند تحميل الفصل، أي أنه يمكن استخدامه أو تنفيذه. يمكن تنفيذ كل شيء بدون كائنات. على العكس من ذلك، إذا لم يكن هناك ثابت، فيجب الوصول إليه من خلال الكائن.