Посібник із статичного ключового слова на Java

1. Вступ

У цій статті ми детально вивчимо статичне ключове слово мови Java. Ми знайдемо, як ми можемо застосувати ключове слово static до змінних, методів, блоків, вкладених класів і яку різницю це має.

2. Анатомія статичного ключового слова

У мові програмування Java ключове слово static вказує на те, що конкретний член належить самому типу, а не екземпляру цього типу .

Це означає, що створено лише один екземпляр цього статичного члена, який є спільним для всіх екземплярів класу.

Ключове слово можна застосувати до змінних, методів, блоків та вкладеного класу.

3. Статичні поля (або змінні класу)

У Java, якщо поле оголошено статичним , тоді створюється та передається рівно одна копія цього поля та ділиться між усіма екземплярами цього класу . Не має значення, скільки разів ми ініціалізуємо клас; завжди буде лише одна копія статичного поля, що належить йому. Значення цього статичного поля буде спільним для всіх об’єктів будь-якого з них будь-якого іншого класу.

З точки зору пам'яті статичні змінні потрапляють до певного пулу в пам'яті JVM, який називається Metaspace (до Java 8 цей пул називався Permanent Generation або PermGen, який був повністю видалений і замінений на Metaspace).

3.1. Приклад статичного поля

Припустимо, у нас є клас Car з кількома атрибутами (змінними екземпляра) . Щоразу, коли нові об'єкти ініціалізуються з цього проекту автомобіля , кожен новий об'єкт матиме свою окрему копію цих змінних екземпляра.

Однак, припустимо, ми шукаємо змінну, яка містить підрахунок кількості об'єктів Car , які ініціалізовані, і є спільною для всіх екземплярів, так що вони можуть отримати до неї доступ та збільшити її після їх ініціалізації.

Ось де входять статичні змінні:

public class Car { private String name; private String engine; public static int numberOfCars; public Car(String name, String engine) { this.name = name; this.engine = engine; numberOfCars++; } // getters and setters }

Тепер для кожного об’єкта цього класу, який ініціалізується, збільшується однакова копія змінної numberOfCars . Отже, для цього випадку будуть справедливими такі твердження:

@Test public void whenNumberOfCarObjectsInitialized_thenStaticCounterIncreases() { new Car("Jaguar", "V8"); new Car("Bugatti", "W16"); assertEquals(2, Car.numberOfCars); }

3.2. Вимушені причини використання статичних полів

  • Коли значення змінної не залежить від об'єктів
  • Коли значення має бути спільним для всіх об'єктів

3.3. Основні моменти, які слід пам’ятати

  • Оскільки статичні змінні належать до класу, до них можна отримати безпосередній доступ за допомогою імені класу і не потребують посилання на об'єкт
  • статичні змінні можуть бути оголошені лише на рівні класу
  • статичні поля можна отримати без ініціалізації об'єкта
  • Хоча ми можемо отримати доступ до статичних полів, використовуючи посилання на об'єкт (наприклад, ford.numberOfCars ++ ), нам слід утриматися від його використання, оскільки в цьому випадку стає важко зрозуміти, чи це змінна екземпляра, чи змінна класу; натомість ми завжди повинні посилатися на статичні змінні з використанням імені класу (наприклад, у цьому випадку Car.numberOfCars ++ )

4. Статичні методи (або методи класу)

Подібно до статичних полів, статичні методи також належать до класу замість об'єкта, тому їх можна викликати, не створюючи об'єкт класу, в якому вони перебувають. Вони призначені для використання без створення об’єктів класу.

4.1. Приклад статичного методу

статичні методи зазвичай використовуються для виконання операції, яка не залежить від створення екземпляра.

Якщо є код, який повинен бути спільним для всіх екземплярів цього класу, напишіть цей код статичним методом:

public static void setNumberOfCars(int numberOfCars) { Car.numberOfCars = numberOfCars; }

статичні методи також широко використовуються для створення службових або допоміжних класів, щоб їх можна було отримати без створення нового об'єкта цих класів.

Просто подивіться на класи утиліти Collections або Math від JDK, StringUtils від Apache або CollectionUtils від Spring і зауважте, що всі методи є статичними .

4.2. Вимушені причини використання статичних методів

  • Доступ до / керування статичними змінними та іншими статичними методами, які не залежать від об’єктів
  • статичні методи широко використовуються в утилітах та допоміжних класах

4.3. Основні моменти, які слід пам’ятати

  • статичні методи в Java вирішуються під час компіляції. Оскільки перевизначення методу є частиною поліморфізму виконання, тому статичні методи не можна замінити
  • абстрактні методи не можуть бути статичними
  • статичні методи не можуть використовувати це або супер ключові слова
  • Допустимими є наступні комбінації екземпляра, методів класу та змінних:
    1. Методи екземпляра можуть безпосередньо отримувати доступ як до методів екземпляра, так і до змінних екземпляра
    2. Методи екземпляра також можуть отримувати безпосередній доступ до статичних змінних та статичних методів
    3. статичні методи можуть отримати доступ до всіх статичних змінних та інших статичних методів
    4. статичні методи не можуть отримати безпосередній доступ до змінних екземпляра та методів екземпляра ; для цього їм потрібна якась посилання на об’єкт

5. Статичний блок

Статичний блок використовується для ініціалізації статичних змінних. Хоча статичні змінні можна ініціалізувати безпосередньо під час оголошення, бувають ситуації, коли нам потрібно виконати багаторядкову обробку.

У таких випадках статичні блоки стають в нагоді.

Якщо статичні змінні вимагають додаткової логіки з декількома операторами під час ініціалізації, тоді можна використовувати статичний блок.

5.1. Статичний блок Приклад

Припустимо, ми хочемо ініціалізувати об’єкт списку з деякими заздалегідь визначеними значеннями.

Це стає легко за допомогою статичних блоків:

public class StaticBlockDemo { public static List ranks = new LinkedList(); static { ranks.add("Lieutenant"); ranks.add("Captain"); ranks.add("Major"); } static { ranks.add("Colonel"); ranks.add("General"); } }

У цьому прикладі було б неможливо ініціалізувати об’єкт List з усіма початковими значеннями разом з оголошенням; і саме тому ми використали тут статичний блок.

5.2. Вимушені причини використання статичних блоків

  • Якщо для ініціалізації статичних змінних потрібна додаткова логіка, крім призначення
  • Якщо ініціалізація статичних змінних піддається помилкам і вимагає обробки винятків

5.3. Основні моменти, які слід пам’ятати

  • Клас може мати кілька статичних блоків
  • статичні поля та статичні блоки вирішуються та виконуються в тому ж порядку, що і в класі

6. Статичний клас

Мова програмування Java дозволяє нам створювати клас у класі. Це забезпечує переконливий спосіб групування елементів, які будуть використовуватися лише в одному місці, це допомагає зробити наш код більш організованим і читабельним.

Архітектура вкладеного класу розділена на два:

  • вкладені класи, які оголошені статичними , називаються статичними вкладеними класами, тоді як,
  • nested classes that are non-static are called inner classes

The main difference between these two is that the inner classes have access to all member of the enclosing class (including private), whereas the static nested classes only have access to static members of the outer class.

In fact, static nested classes behaved exactly like any other top-level class but enclosed in the only class which will access it, to provide better packaging convenience.

6.1. Example of static Class

The most widely used approach to create singleton objects is through static nested class is it doesn't require any synchronization and is easy to learn and implement:

public class Singleton { private Singleton() {} private static class SingletonHolder { public static final Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } }

6.2. Compelling Reasons to Use a static Inner Class

  • Grouping classes that will be used only in one place increases encapsulation
  • The code is brought closer to the place that will be only one to use it; this increases readability and code is more maintainable
  • If nested class doesn't require any access to it's enclosing class instance members, then it's better to declare it as static because this way, it won't be coupled to the outer class and hence will be more optimal as they won't require any heap or stack memory

6.3. Key Points to Remember

  • static nested classes do not have access to any instance members of the enclosing outer class; it can only access them through an object's reference
  • статичні вкладені класи можуть отримати доступ до всіх статичних членів класу, що включає, включаючи приватні
  • Специфікація програмування Java не дозволяє оголосити клас верхнього рівня як статичний ; лише класи всередині класів (вкладені класи) можуть бути зроблені як статичні

7. Висновок

У цій статті ми побачили дію статичного ключового слова. Ми також читаємо про причини та переваги використання статичних полів, статичних методів, статичних блоків та статичних внутрішніх класів.

Як завжди, ми можемо знайти повний код на GitHub.