JavaRush/Курси/Java Syntax Zero/Особливості роботи зі змінними

Особливості роботи зі змінними

Відкрита

1. Константи

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

Отже, як оголосити незмінювану змінну (константу) в Java? Для цього є спеціальне ключове слово — final. Створення незмінюваної змінної має такий самий вигляд, як і створення звичайної, тільки перед типом змінної слід написати слово final:

final тип ім'я = значення;

Якщо ви спробуєте присвоїти final-змінній інше значення, ваша програма просто не скомпілюється.

final-змінну обов'язково треба ініціалізувати (присвоїти їй значення) під час оголошення. Це правило має один виняток: можна перенести ініціалізацію змінної класу в конструктор. Однак про це ви дізнаєтеся на 10-му рівні.

Щоб зменшити кількість ключових слів, розробники Java використовують слово final не тільки для оголошення констант. Метод і навіть клас теж можуть бути final. Методи, оголошені як final, не можна перевизначати (override), а клас, оголошений як final, не може бути базовим класом для успадкування.

Модифікатор final можна вказувати перед будь-якими змінними: локальними, параметрами, полями класу і статичними змінними.

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

Приклад:

final int[] data = {1, 2, 3, 4, 5, 6};

data = {6, 7, 8, 9};

data[0] = 0;
data[1] = 0;
data[2] = 0;
Створюємо масив.

Так не можна: змінну data оголошено як final.

А так можна.
І так можна.

Глобальні константи

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

Приклади:

class Solution
{
   public static final String SOURCE_ROOT = "c:\\projects\\my\\";
   public static final int DISPLAY_WIDTH = 1024;
   public static final int DISPLAY_HEIGHT = 768;
}

7
Задача
Java Syntax Zero,  7 рівень6 лекція
Недоступна
Згадуємо геометрію
Згадуємо геометрію
7
Задача
Java Syntax Zero,  7 рівень6 лекція
Недоступна
Усе, що потрібно знати про Землю
Усе, що потрібно знати про Землю

2. Затінення змінних

Як ми вже казали, не можна в одному методі створити кілька локальних змінних з однаковими іменами. У різних методах — можна.

А цього ви, напевно, не знаєте: змінним класу і локальним змінним методу дозволено мати однакові імена.

Приклад:

Код Доступність змінних
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     sum = sum + data;
     int sum = data * 2;
     count++;
   }
}


count
count, sum
count, sum
count, sum
count, sum, data
count, sum, data
count, sum, data
count, sum, data
count, sum

У методі add ми оголосили локальну змінну sum, і вона до кінця дії методу перекриває (або ще кажуть затіняє) собою змінну класу sum.

Ну гаразд, скажете ви, навіть в якомусь сенсі очікувана поведінка. Але це ще не все. Виявляється, якщо змінну класу затіняє локальна змінна, у методі все-таки є спосіб звернутися до змінної класу. Для цього потрібно перед її іменем написати ключове слово this:

this.ім'я

Ось приклад, в якому конфлікт імен успішно вирішується:

Код Доступність змінних
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     this.sum = this.sum + data;
     count++;
   }
}


this.count
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum, data
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum

Змінні count і sum доступні всюди як із ключовим словом this, так і без нього. У тих рядках, де локальна змінна sum затіняє змінну класу sum, доступ до змінної класу sum можливий тільки за умови застосування this.

Якщо затіняється не просто змінна класу, а статична змінна класу, звертатися до неї потрібно не через this, а через ім'я класу:

ClassName.ім'я

Приклад:

Код Доступність змінних
public class Solution
{
   public static int count = 0;
   public static int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     Solution.sum = Solution.sum + data;
     count++;
   }
}

Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum, data
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum

Статичні змінні count і sum доступні всюди як із префіксом у вигляді імені класу Solution, так и без нього. У тих рядках, де локальна змінна sum затіняє змінну класу sum, доступ до змінної класу sum можливий тільки за умови застосування префікса Solution.


7
Задача
Java Syntax Zero,  7 рівень6 лекція
Недоступна
Облік працівників
Облік працівників

3. Змінні всередині циклу for

І ще один маленький, але цікавий факт.

Є ще одне місце, де в особливий спосіб оголошується змінна — це цикл for.

Якщо ви пам'ятаєте, зазвичай у циклі for в круглих дужках оголошується змінна-лічильник. І яка ж буде область видимості цієї змінної? Адже вона не міститься в тілі циклу — значить, її буде видно по всьому методу? Чи все-таки ні?

Правильна відповідь така: змінну, оголошену в заголовку циклу for, видно лише в тілі циклу і в заголовку циклу for.

Приклад:

Код Доступність змінних
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a

Отож ви завжди можете в своєму коді послідовно написати кілька циклів зі змінною-лічильником із однаковим іменем — проблем не буде.

Приклад:

Код Доступність змінних
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a, i
a, i
a, i
a
a
a

Коментарі (16)
  • популярні
  • нові
  • старі
Щоб залишити коментар, потрібно ввійти в систему
Dmytrii
Рівень 40
15 червня 2024, 13:13
с каких пор население - это константа???
Ян Третьяк
Рівень 29
12 грудня 2023, 22:58
Не розумію нащо цей приклад:
final int[] data = {1, 2, 3, 4, 5, 6};

data = {6, 7, 8, 9};

data[0] = 0;
data[1] = 0;
data[2] = 0;
На скільки я розумію (навіть спробував), якщо ми вже оголосили масив, без "final", то ми не можемо просто взяти і написати що він тепер буде з іншими значеннями, а тим паче іншого розміру. Чи я щось не догоняю?
De Stroy
Рівень 10
6 квітня 2024, 22:38
int[] data = new int[] {1, 2, 3};
data = new int[] {3, 4, 5, 6};
System.out.println(Arrays.toString(data));
Без final, можемо сказати, що data посилається на новий масив іншого розміру. Якщо поставити final, то буде помилка при компіляції.
Alex
Рівень 2
18 серпня 2024, 20:07
простіше кажучи: змінна data містить в собі не масив, а ПОСИЛАННЯ на нього в пам'яті. Це означає що ти не можеш змінити саме ПОСИЛАННЯ, але сам масив на яке це посилання вказує - змінити можна. В банці з-під огірків листок з адресою, куди поклали огірки. Якщо ця банка створена з final - ти не можеш змінити листок з адресою, але ти завжди можеш глянути на листок, піти за вказаною адресою і взяти собі огірок
7 травня 2023, 17:34
В першому завданні трохи не зрозуміла, вказано в лекції, що статичні константи зазвичай називаються великими буквами, але в самому завданні статична константа з великими буквами не приймається. То все ж, яка різниця? Чому одні можна називати великими, а інші ні?
Василь trainee в Kindgeek
22 липня 2023, 16:24
це всього забаганки місцевого валідатора. Не звертайте увагу. Але я думаю що на 10 левелі ви вже і самі до цього дійшли )
Denis Polyak
Рівень 51
31 березня 2023, 08:57
АХАХАХА з яких пір популяція (населення планети) це стала велечина?
Kostiantyn Bogatyrchuk Двірник в УМАНСЬКЕ РЕУ №3, КПExpert
22 січня 2023, 10:51
от читаю і не розумію, чому не подавалося цієї нформації раніше, коли нам подавали інформацію про типи змінних. Скільки разів бувало, що я оголошував змінні у коді і не міг зрозуміти чому при компіляції виникає конфлікт.
Roma Chernesh
Рівень 16
17 грудня 2022, 17:57
Хто розуміє, чом у статичному методі main ми можемо використовувати нестатичні змінні?
les_yeux_blancs QA Automation Engineer
20 квітня 2023, 20:26
можна приклад?
Roma Chernesh
Рівень 16
10 травня 2023, 09:53
Так! Наскільки розумію, що у static методы змінні можуть бути будь-які: public static void main(String[] args) { int a = 0; for (int i = 0; i < 10; i++) { System.out.println(i); } System.out.println("end"); }
les_yeux_blancs QA Automation Engineer
10 травня 2023, 17:53
Так це внутрішні змінні метода, а не поля класу, тут потрібно розрізняти Все, що є оголошеним усередині методу, є доступним лише для цього методу, створюється кожен раз заново при його виконання й видаляється після
Pan Vitali Moroz
Рівень 51
12 вересня 2022, 20:02
Дякую, цікаво
YPon
Рівень 22
12 вересня 2021, 13:16
this.salary = this.salary + salary; Так лучше))
2 лютого 2022, 20:37
Мабуть, малося на увазі, що в метод setSalary подається не те, на скільки змінилася зарплата, а змінна int salary - яка просто вказує нову зарплату. а так вийде, була в мене зарплата 1000, мені збільшили її на 200, начебто непогано, тепер вона в мене 1200. Але ні, слава програмістам, зарплата стала this.salary = this.salary + salary, тобто 1000 + 1200, тобто 2200, але, я вважаю, шеф буде проти🤣
Me Lex
Рівень 12
15 березня 2022, 18:50
Не зовсім ) Бо зарплата не змінить а збільшиться ) Якщо ти працівник то буде не погано Але роботодавець не оціне :D