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



Комментарии (355)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Anonymous #3585174 Уровень 33
7 июня 2025
like
Хэйли Эванс Уровень 19
6 марта 2025
Почему переменная "population" должна быть final если это ниразу не константа)
LisoEdoEd Уровень 19 Student
12 марта 2025
Зачем так заморачиваешься, Это всего лишь пример, задачка. Чтобы ты решила.
Хэйли Эванс Уровень 19
12 марта 2025
потому что обьясняется константа и на ее примере она таковой и должна являться, а вообще изза этой неточности вышло не с первого раза вот и бешусь :DD
LisoEdoEd Уровень 19 Student
13 марта 2025
В любом случает численность населения никогда не может быть константой)
Хэйли Эванс Уровень 19
13 марта 2025
ну так и я о том же)
Anonymous #3560516 Уровень 10
21 апреля 2025
полностью тебя поддерживаю, вышло тоже самое и со мной
23 апреля 2025
потому что джавараш дает такие примеры, которые заставляют не понять тему как можно быстрее, а помогают заморочиться и взбеситься)) Примеры на начальном уровне, как по мне, должны быть максимально лаконичные и понятные, чтобы у человека не пропадала мотивация от лишней когнитивной нагрузки.
Romaha Уровень 14
25 мая 2025
А в чём была неточность, из-за которой у вас не решилась задачка с первого раза?🙂 Вам ведь в ТЗ указали --> "Переменную population класса Earth нужно переделать в глобальную переменную". В нашем деле торопиться нельзя🙂
Diamond Уровень 15
14 февраля 2025
Почему я должен в переменную equatorLength ставить нижнее подчеркивание если в условие она без _ ?
Fend 1050 Уровень 6
16 февраля 2025
Для имен таких переменных существует специальный стиль написания: они пишутся заглавными буквами, а в качестве разделителя слов выступает символ подчеркивания.
Амнистия Уровень 10
26 февраля 2025
Где-то нам про это рассказывали? Тоже выбесило
Alexey Reutov Уровень 16
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 Ну как так ?☹️
Евгений Пикин Уровень 46
12 декабря 2024
Ну всё правильно. Пи - константа. Остальные - нет.
Soup🍲 Уровень 15
17 декабря 2024
так кто знает,может именно в этом случае,решили сделать константы не только пи .константы утверждает тот,кто пишет код .считаю,лучше переменные перенести в метод,кроме ПИ
Евгений Пикин Уровень 46
18 декабря 2024
Ну это же общий пример. Константы утверждает мироздание) Пи мы изменить не можем. Остальное можем. В этом и смысл константы.
Grigoryvvv Уровень 11 Expert
8 декабря 2024
09.12.24/ 7 уровень
Матвей Уровень 16
24 января 2025
что-то ты застрял на восьмом
s0xzwasd Уровень 12
20 мая 2025
Двигаемся дальше?
Grigoryvvv Уровень 11 Expert
22 сентября 2025
Поехали ))
Grigoryvvv Уровень 11 Expert
22 октября 2025
Даниил, давай учиться )
Bola Kharebov Уровень 10
2 декабря 2024
"Обратите внимание, что final — это всего лишь защита от изменения переменной. Если переменная хранит ссылку на объект, объект все-таки менять можно." Если быть точнее, то final — это всего лишь защита от изменения значения в переменной. Если переменная хранит ссылку на объект, ссылку в переменной не получится заменить, соответственно заменить объект на который ссылается переменная не получится, а вот обратиться к параметрам объекта (полям, либо переменным кому как понятнее) можно. Соответственно заменить объект нельзя, а изменить объект можно.
Max Уровень 73
24 октября 2024
Пока читал про this всё было хорошо, а вот в видео как то меня запутали объяснения, пойду погууглю :\
Hanna Уровень 8
29 ноября 2024
Речь идет о каких-то сторонних видео? У меня в лекциях никаких видео нет 🧐
Max Уровень 73
30 ноября 2024
🤷‍♂️
BagamedJava Уровень 11
2 декабря 2024
Рекомендую - https://metanit.com/java/tutorial/3.1.php Грубо говоря this говорит что мы ссылаемся на эту переменную

public class This{
    private String name; // Имя1
public void setName(String name){ //Имя2
    this.name = name; // Имя1 == Имя2. То есть мы говорим, что берем именно имя1. 
}
}
Max Уровень 73
3 декабря 2024
this говорит, что мы ссылаемся на переменную класса
Roman Уровень 75
23 декабря 2024
В зависимости от подписки premium и university. Во второй подписки есть видео.