JavaRush /مدونة جافا /Random-AR /10 ملاحظات حول المعدل الثابت في Java

10 ملاحظات حول المعدل الثابت في Java

نشرت في المجموعة
يرتبط المعدل الثابت في Java مباشرة بالفئة. إذا كان الحقل ثابتًا، فهو ينتمي إلى الفصل، وإذا كانت الطريقة ثابتة، فهو نفسه: إنه ينتمي إلى الفصل. وبناءً على ذلك، يمكنك الوصول إلى أسلوب أو حقل ثابت باستخدام اسم الفئة. على سبيل المثال، إذا كان حقل العدد ثابتًا في فئة العداد، فيمكنك الوصول إلى المتغير باستخدام استعلام مثل: Counter.count. 10 ملاحظات حول المُعدِّل الثابت في Java - 1قبل أن نبدأ بالملاحظات، دعونا نتذكر (وربما نكتشف) ما هو الثابت وما يمكن أن يكون ثابتًا في Java. Static هو مُعدِّل يتم تطبيقه على حقل أو كتلة أو طريقة أو فئة داخلية. يشير هذا المعدل إلى أن الموضوع مرتبط بالفئة الحالية.

الحقول الثابتة

عندما نشير إلى متغير على مستوى الفئة، فإننا نشير إلى أن القيمة تنتمي إلى فئة ما. إذا لم تقم بذلك، فسيتم ربط قيمة المتغير بكائن تم إنشاؤه باستخدام هذه الفئة. ماذا يعني ذلك؟ 10 ملاحظات حول المعدل الثابت في Java - 2والحقيقة هي أنه إذا لم يكن المتغير ثابتًا، فإن كل كائن جديد من هذه الفئة سيكون له قيمته الخاصة من هذا المتغير، من خلال تغييره نغيره حصريًا في كائن واحد: على سبيل المثال، لدينا فئة Car مع غير -المتغير الساكن:
public class Car {
  int km;
}
ثم بشكل رئيسي:
Car orangeCar = new Car();
orangeCar.km = 100;

Car blueCar = new Car();
blueCar.km = 85;

System.out.println("Orange car - " + orangeCar.km);
System.out.println("Blue car - " + blueCar.km);
الناتج الذي نحصل عليه هو:

Orange car - 100
Blue car - 85
كما ترون، كل كائن له متغير خاص به، والذي يحدث التغيير لهذا الكائن فقط. حسنًا، إذا كان لدينا متغير ثابت، فإن هذه القيمة العامة هي نفسها للجميع: الآن لدينا سيارة بها متغير ثابت:
public class Car {
  static int km;
}
بعد ذلك سيتم إخراج نفس الكود بشكل رئيسي إلى وحدة التحكم:

Orange car - 85
Blue car - 85
ففي نهاية المطاف، لدينا متغير واحد لكل منا، وفي كل مرة نقوم بتغييره. عادةً لا يتم الوصول إلى المتغيرات الثابتة عن طريق مرجع الكائن - orangeCar.km، ولكن عن طريق اسم الفئة - Car.km

كتلة ثابتة

هناك نوعان من كتل التهيئة - عادية وثابتة. تهدف الكتلة إلى تهيئة المتغيرات الداخلية. إذا كانت الكتلة عادية، فسيتم تهيئة المتغيرات الداخلية للكائن بها، ولكن إذا كانت ثابتة، فسيتم تعيين متغيرات ثابتة (أي متغيرات الفئة) لها. مثال لفئة مع كتلة تهيئة ثابتة:
public class Car {
  static int km;

  static {
     km = 150;
  }
}

طريقة ثابتة

تختلف الطرق الثابتة عن الطرق العادية من حيث أنها مرتبطة أيضًا بفئة بدلاً من كائن. من الخصائص المهمة للطريقة الثابتة أنها يمكنها الوصول فقط إلى المتغيرات/الطرق الثابتة. على سبيل المثال، دعونا نلقي نظرة على فئة ستكون نوعًا من العداد الذي يتتبع استدعاءات الطريقة:
public class Counter {
  static int count;

  public static void invokeCounter() {
     count++;
     System.out.println("Current counter value - " + count);
  }
}
دعنا نسميها بشكل رئيسي:
Counter.invokeCounter();
Counter.invokeCounter();
Counter.invokeCounter();
ونحصل على الإخراج إلى وحدة التحكم:

Текущее meaning счётчика - 1
Текущее meaning счётчика - 2
Текущее meaning счётчика - 3

فئة ثابتة في جافا

فقط الطبقة الداخلية يمكن أن تكون فئة ثابتة. مرة أخرى، هذه الفئة مرتبطة بالطبقة الخارجية، وإذا ورثت الطبقة الخارجية فئة أخرى، فلن يتم توريث هذه الطبقة. علاوة على ذلك، يمكن وراثة هذه الفئة، تمامًا كما يمكن توريثها من أي فئة أخرى وتنفيذ واجهة. في الأساس، لا تختلف الفئة المتداخلة الثابتة عن أي فئة داخلية أخرى، باستثناء أن كائنها لا يحتوي على مرجع لكائن الطبقة الخارجية الذي أنشأها. ومع ذلك، فإن هذا يجعل الفئة الثابتة أكثر تشابهًا مع الفئة العادية غير المتداخلة، لأن الاختلاف الوحيد هو أنها ملتفة في فئة أخرى. في بعض الحالات، يعد ذلك ميزة بالنسبة لنا، حيث يمكننا من خلاله الوصول إلى المتغيرات الثابتة الخاصة بالطبقة الخارجية. مثال على فئة ثابتة متداخلة:
public class Vehicle {

  public static class Car {
     public int km;
  }
}
إنشاء مثيل لهذه الفئة وتعيين قيمة المتغير الداخلي:
Vehicle.Car car = new Vehicle.Car();
car.km = 90;
لاستخدام الأساليب الثابتة/المتغيرات/الفئة، لا نحتاج إلى إنشاء كائن من تلك الفئة. وبطبيعة الحال، ينبغي أن تؤخذ معدلات الوصول في الاعتبار. على سبيل المثال، privateلا يمكن الوصول إلى الحقول إلا داخل الفئة التي تم الإعلان عنها. الحقول protectedمتاحة لجميع الفئات داخل الحزمة ( package )، وكذلك لجميع الفئات التابعة خارج الحزمة. لمزيد من التفاصيل، راجع المقالة " خاص مقابل محمي مقابل عام ". لنفترض أن هناك طريقة ثابتة increment()في الفصل Counterتتمثل مهمتها في زيادة العداد count. لاستدعاء هذه الطريقة، يمكنك استخدام استدعاء النموذج Counter.increment(). ليست هناك حاجة لإنشاء مثيل لفئة Counterللوصول إلى حقل أو طريقة ثابتة. هذا هو الفرق الأساسي بين الكائنات الثابتة وغير الثابتة (أعضاء الفئة). اسمحوا لي أن أذكرك مرة أخرى أن أعضاء الفصل الثابت ينتمون مباشرة إلى الفصل، وليس إلى مثيله. أي أن قيمة المتغير الثابت countستكون هي نفسها لجميع الكائنات من النوع Counter. لاحقًا في هذه المقالة، سنلقي نظرة على الجوانب الأساسية لاستخدام المعدل الثابت في Java، بالإضافة إلى بعض الميزات التي ستساعدك على فهم مفاهيم البرمجة الأساسية.

ما يجب أن يعرفه كل مبرمج عن المعدل الثابت في Java

في هذا القسم، سنلقي نظرة على أساسيات استخدام الأساليب والحقول والفئات الثابتة. لنبدأ بالمتغيرات.
  1. لا يمكنك الوصول إلى الأعضاء غير الثابتين في الفصل ضمن سياق ثابت، مثل الطريقة أو الكتلة. سيؤدي تجميع الكود أدناه إلى حدوث خطأ:

    public class Counter{
    private int count;
    public static void main(String args[]){
       System.out.println(count); //compile time error
    }}

    وهذا أحد الأخطاء الأكثر شيوعًا التي يرتكبها مبرمجو Java، وخاصة المبتدئين. نظرًا لأن الطريقة mainثابتة، ولكن المتغير ليس كذلك، ففي هذه الحالة ستؤدي countالطريقة printlnداخل الطريقة إلى ظهور "خطأ في وقت الترجمة".main

  2. В отличие от локальных переменных, статические поля и методы НЕ потокобезопасны (Thread-safe) в Java. На практике это одна из наиболее частых причин возникновения проблем связанных с безопасностью мультипоточного программирования. Учитывая что каждый экземпляр класса имеет одну и ту же копию статической переменной, то такая переменная нуждается в защите — «залочивании» классом. Поэтому при использовании статических переменных, убедитесь, что они должным образом синхронизированы (synchronized), во избежание проблем, например таких How «состояние гонки» (race condition).

  3. Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый an object для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы How нельзя лучше подходят в качестве методов-фабрик (factory), и методов-утorт (utility). Класс java.lang.Math — замечательный пример, в котором почти все методы статичны, по этой же причине классы-утorты в Java финализированы (final).

  4. Другим важным моментом является то, что вы НЕ можете переопределять (Override) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass) instead of переопределения. Это явление известно How сокрытие методов (hiding methods). Это означает, что при обращении к статическому методу, который объявлен How в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:

    class Vehicle{
         public static void  kmToMiles(int km){
              System.out.println("Inside parent class/static method");
         } }
    
    class Car extends Vehicle{
         public static void  kmToMiles(int km){
              System.out.println("Inside child class/static method ");
         } }
    
    public class Demo{
       public static void main(String args[]){
          Vehicle v = new Car();
           v.kmToMiles(10);
      }}

    Вывод в консоль:

    Внутри родительского класса/статического метода

    Код наглядно демонстрирует: несмотря на то, что an object имеет тип Car, вызван статический метод из класса Vehicle, т.к. произошло обращение к методу во время компиляции. И заметьте, ошибки во время компиляции не возникло!

  5. Объявить статическим также можно и класс, за исключением классов верхнего уровня. Такие классы известны How «вложенные статические классы» (nested static class). Они бывают полезными для представления улучшенных связей. Яркий пример вложенного статического класса — HashMap.Entry, который предоставляет структуру данных внутри HashMap. Стоит заметить, также How и любой другой внутренний класс, вложенные классы находятся в отдельном файле .class. Таким образом, если вы объявor пять вложенных классов в вашем главном классе, у вас будет 6 файлов с расширением .class. Ещё одним примером использования является объявление собственного компаратора (Comparator), например компаратор по возрасту (AgeComparator) в классе сотрудники (Employee).

  6. Модификатор static также может быть объявлен в статичном блоке, более известным How «Статический блок инициализации» (Static initializer block), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок НЕ может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике, любое исключение возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему.

  7. Полезно знать, что статические методы связываются во время компиляции, в отличие от связывания виртуальных or не статических методов, которые связываются во время исполнения на реальном an objectе. Следовательно, статические методы не могут быть переопределены в Java, т.к. полиморфизм во время выполнения не распространяется на них. Это важное ограничение, которое необходимо учитывать, объявляя метод статическим. В этом есть смысл, только тогда, когда нет возможности or необходимости переопределения такого метода классами-наследниками. Методы-фабрики и методы-утorты хорошие образцы применения модификатора static. Джошуа Блох выделил несколько преимуществ использования статичного метода-фабрики перед конструктором, в книге «Effective Java», которая является обязательной для прочтения каждым программистом данного языка.

  8. Важным свойством статического блока является инициализация. Статические поля or переменные инициализируются после загрузки класса в память. Порядок инициализации сверху вниз, в том же порядке, в Howом они описаны в исходном файле Java класса. Поскольку статические поля инициализируются на потокобезопасный манер, это свойство также используется для реализации паттерна Singleton. Если вы не используется список Enum How Singleton, по тем or иным причинам, то для вас есть хорошая альтернатива. Но в таком случае необходимо учесть, что это не «ленивая» инициализация. Это означает, что статическое поле будет проинициализировано ещё ДО того How кто-нибудь об этом «попросит». Если an object ресурсоёмкий or редко используется, то инициализация его в статическом блоке сыграет не в вашу пользу.

  9. أثناء عملية التسلسل، تمامًا مثل transientالمتغيرات، لا يتم إجراء تسلسل للحقول الثابتة. في الواقع، إذا قمت بحفظ أي بيانات في حقل ثابت، فبعد إلغاء التسلسل، سيحتوي الكائن الجديد على قيمته الأساسية (الافتراضية)، على سبيل المثال، إذا كان الحقل الثابت متغيرًا من النوع int، فستكون قيمته بعد إلغاء التسلسل صفرًا، إذا النوع floatهو 0.0، إذا كان النوع Object- null. بصراحة، يعد هذا أحد الأسئلة الأكثر شيوعًا فيما يتعلق بالتسلسل في مقابلات Java. لا تقم بتخزين البيانات الأكثر أهمية حول كائن ما في حقل ثابت!

  10. وأخيرا، دعونا نتحدث عن static import. يحتوي هذا المعدل على الكثير من القواسم المشتركة مع العامل القياسي import، ولكن على عكسه، فهو يسمح لك باستيراد واحد أو كل الأعضاء الثابتين للفئة. عند استيراد الأساليب الثابتة، يمكن الوصول إليها كما لو تم تعريفها في نفس الفئة، وبالمثل عند استيراد الحقول، يمكننا الوصول إليها دون تحديد اسم الفئة. تم تقديم هذه الميزة في Java الإصدار 1.5، وعند استخدامها بشكل صحيح، تعمل على تحسين إمكانية قراءة التعليمات البرمجية. غالبًا ما يتم العثور على هذا البناء في اختبارات JUnit ، لأن يستخدم جميع مطوري الاختبارات تقريبًا static importأساليب التأكيد، على سبيل المثال، assertEquals()والنسخ المكررة المحملة بشكل زائد. إذا لم يكن هناك شيء واضح، مرحبا بكم للحصول على معلومات إضافية .

هذا كل شئ. يجب أن يعرف كل مبرمج جميع النقاط المذكورة أعلاه حول المعدل الثابت في Java . غطت هذه المقالة المعلومات الأساسية حول المتغيرات الثابتة والحقول والأساليب وكتل التهيئة والواردات. بما في ذلك بعض الخصائص المهمة، والتي تعد معرفتها أمرًا بالغ الأهمية عند كتابة البرامج وفهمها بلغة Java. آمل أن يتقن كل مطور مهاراته في استخدام المفاهيم الثابتة لأن... وهذا مهم جدًا للبرمجة الجادة."
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION