1. Статичні змінні

Коли клас завантажується в пам'ять, для нього відразу створюється статичний об'єкт класу. Цей об'єкт зберігає статичні змінні класу (статичні поля класу). Статичний об'єкт класу існує, навіть якщо не було створено жодного звичайного об'єкта класу.

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

А статична (static) змінна прив'язана до статичного об'єкта класу й завжди існує в одному екземплярі.

Щоб створити статичну змінну класу, потрібно перед її ім'ям написати ключове слово static. Оголошення статичної змінної має такий загальний вигляд:

static Тип ім'я = значення;

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

Тип Значення за замовчуванням
byte
0
short
0
int
0
long
0
float
0.0
double
0.0
char
'\u0000'
(те саме, що й
0
)
boolean
false
Object
і будь-які класи
null

Приклади:

Код Примітка
public static int WIDTH = 100;
public static String message = "Hello";
private static Scanner console;
private static int count = 0;
private static boolean flag;

Щоб звернутися до статичної змінної в її класі, досить просто вказати її ім'я. Щоб звернутися з іншого класу, перед ім'ям статичної змінної потрібно вказати ім'я класу.

Ім'яКласу.змінна

Приклад:

Змінна Клас Звернення до змінної з іншого класу
public static int WIDTH = 100;
Solution
Solution.WIDTH
public static String message = "Hello";
Main
Main.message
private static Scanner console;
JavaGame
Змінну private поза її класом не видно
private static int count = 0;
Counter
Змінну private поза її класом не видно
private static boolean flag;
Arithmetic
Змінну private поза її класом не видно


2. Різниця між статичними й нестатичними змінними

Нестатичні (звичайні) змінні класу оголошуються так само, як і статичні, тільки без ключового слова static.

У чому ж різниця між звичайними й статичними змінними?

Звичайні змінні класу прив'язані до об'єктів свого класу (екземплярів класу), а статичні змінні — до статичного об'єкта класу.

Якщо екземплярів класу декілька, у кожному з них є своя копія нестатичних (звичайних) змінних класу. Статичні змінні класу завжди існують тільки в одному екземплярі, який знаходиться всередині статичного об'єкта класу.

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

Приклад:

Звернення до поля класу за допомогою посилання на об'єкт класу
public class DataInfo
{
   public int value = 100;
}

public class Solution
{
   public static void main(String[] args)
   {
      DataInfo info = new DataInfo();
      System.out.println(info.value);
   }
}

Звертатися до статичних змінних можна звідки завгодно (з урахуванням модифікаторів видимості): зі звичайних методів, зі статичних методів того самого класу, з методів інших класів і т. ін.

Приклад:

Звернення до статичного поля класу без використання посилання на об'єкт класу
public class DataInfo
{
   public static int value = 100;
}

public class Solution
{
   public static void main(String[] args)
   {
      System.out.println(DataInfo.value);
   }
}

Об'єкти в пам'яті

Припустімо, у нас є клас Person із 4 полями: два статичних, а два — ні.

public class Person
{
   public static int count = 0;
   public static int sum = 0;
   public int age = 0;
   public String name;
}

Одразу після завантаження класу

Коли Java-машина завершить завантаження класу Person, у пам'яті буде така картина:

Після створення першого об'єкта

Після створення об'єкта класу Person картина стане такою:

Зверніть увагу, що, хоча об'єкти мають по дві змінні, це різні змінні: у звичайного об'єкта — звичайні, у статичного — статичні.

Потрібно більше об'єктів

Тепер створімо ще два об'єкти типу Person. Нова картина буде такою:

Зверніть увагу, що кожний об'єкт має власні змінні age і name.



3. Видалення й додавання модифікатора static

Перетворення статичної на звичайну

Що буде, якщо перетворити статичну змінну на звичайну, тобто видалити в неї модифікатор static? Візьмімо, наприклад, змінну static int sum.

Змінений код матиме такий вигляд:

public class Person
{
   public static int count = 0;
   public int sum = 0;
   public int age = 0;
   public String name;
}

А картина в пам'яті стане такою:

Статична змінна в статичного об'єкта зникла, натомість у кожного об'єкта з'явилася своя власна змінна sum.

Перетворення зі звичайної в статичну

Можна зробити й навпаки: додати перед звичайними змінними класу модифікатор static — тоді ці змінні зникнуть у всіх об'єктів і натомість з'являться в статичного об'єкта. Припустімо, ми вирішили зробити статичними змінні age і name. Тоді код матиме такий вигляд:

public class Person
{
   public static int count = 0;
   public int sum = 0;
   public static int age = 0;
   public static String name;
}

А картина в пам'яті стане такою: