JavaRush /Курсы /Java Syntax Pro /Нюансы работы с переменными

Нюансы работы с переменными

Java Syntax Pro
6 уровень , 5 лекция
Открыта

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 = new int[]{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;
}


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.



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



Комментарии (358)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Роман Брагин Уровень 8
5 июня 2026
05.06.2026 - 7 уровень
Anna Klushkina Уровень 51
6 января 2026
⛏ 06.01.26 - 10 уровень
Роман Зарубин Уровень 8
9 декабря 2025
Работаем ...
Anonymous #3585174 Уровень 33
7 июня 2025
like
Хэйли Эванс Уровень 19
6 марта 2025
Почему переменная "population" должна быть final если это ниразу не константа)
LisoEdoEd Уровень 5 Student
12 марта 2025
Зачем так заморачиваешься, Это всего лишь пример, задачка. Чтобы ты решила.
Хэйли Эванс Уровень 19
12 марта 2025
потому что обьясняется константа и на ее примере она таковой и должна являться, а вообще изза этой неточности вышло не с первого раза вот и бешусь :DD
LisoEdoEd Уровень 5 Student
13 марта 2025
В любом случает численность населения никогда не может быть константой)
Хэйли Эванс Уровень 19
13 марта 2025
ну так и я о том же)
Anonymous #3560516 Уровень 10
21 апреля 2025
полностью тебя поддерживаю, вышло тоже самое и со мной
23 апреля 2025
потому что джавараш дает такие примеры, которые заставляют не понять тему как можно быстрее, а помогают заморочиться и взбеситься)) Примеры на начальном уровне, как по мне, должны быть максимально лаконичные и понятные, чтобы у человека не пропадала мотивация от лишней когнитивной нагрузки.
Romaha Уровень 17
25 мая 2025
А в чём была неточность, из-за которой у вас не решилась задачка с первого раза?🙂 Вам ведь в ТЗ указали --> "Переменную population класса Earth нужно переделать в глобальную переменную". В нашем деле торопиться нельзя🙂
Diamond Уровень 15
14 февраля 2025
Почему я должен в переменную equatorLength ставить нижнее подчеркивание если в условие она без _ ?
Fend 1050 Уровень 2
16 февраля 2025
Для имен таких переменных существует специальный стиль написания: они пишутся заглавными буквами, а в качестве разделителя слов выступает символ подчеркивания.
Амнистия Уровень 10
26 февраля 2025
Где-то нам про это рассказывали? Тоже выбесило
Alexey Reutov Уровень 17
2 марта 2025
7 уровень, 6 лекция: 1.Константы: Глобальные константы (Почти в самом начале лекции)
Diamond Уровень 15
14 февраля 2025
Поставьте лайк если любите маму🤡
Юрий Уровень 20
7 февраля 2025
Ложки нет 🕶
21 января 2025
Не много не понял с this, почему не использоваться solution.sum ? this если не путаю используют в конструкторе когда передаем переменную с другого класса дабы присвоить в текущий UPD используем this так как переменная не статическая.
Джон Смит Уровень 8
22 января 2025
Наверное когда объектов класса много, то this.sum - sum этого объекта. А solution.sum теряет смысл, они все solution.sum. Мы это вроде не проходили ещё.
24 января 2025
Как мне обьяснил GPT. this внутри класса используется в случае если переменная класса не статична. А с обьектом когда создаем например Car car = new Car() - в данном случае "()" говорит программе что будем использовать конструктор с this для создание экземпляра класса(присваивать переменную через this из класса в обьект) Если я правильно суть понял)
BigMag2000 Уровень 12
11 декабря 2024
Постановка задачи как всегда хромая "Требования: Модификатор final должен быть установлен всем константам. Константы должны быть переименованы согласно конвенции." А по факту оказывается только для переменной pi Ну как так ?☹️
Евгений Пикин Уровень 1
12 декабря 2024
Ну всё правильно. Пи - константа. Остальные - нет.
Soup🍲 Уровень 15
17 декабря 2024
так кто знает,может именно в этом случае,решили сделать константы не только пи .константы утверждает тот,кто пишет код .считаю,лучше переменные перенести в метод,кроме ПИ
Евгений Пикин Уровень 1
18 декабря 2024
Ну это же общий пример. Константы утверждает мироздание) Пи мы изменить не можем. Остальное можем. В этом и смысл константы.