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;
}

undefined
7
Задача
Java Syntax Pro, 7 уровень, 6 лекция
Недоступна
Вспоминаем геометрию
Посмотри, что делает программа. Расставь модификатор final общепринятым константам (переменным с неизменными значениями).
undefined
7
Задача
Java Syntax Pro, 7 уровень, 6 лекция
Недоступна
Все что нужно знать о Земле
Перед тобой класс Earth - сборник переменных, описывающих определенные характеристики планеты Земля. Сделай из переменных класса Earth глобальные константы. Не забудь переименовать переменные, чтобы они отвечали стилю написания глобальных переменных.

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.


undefined
7
Задача
Java Syntax Pro, 7 уровень, 6 лекция
Недоступна
Учет работников
Перед тобой — цифровая учетная карточка работника. В ней указано его имя, должность и зарплата. Имя работника вряд ли поменяется, а вот должность и зарплата могут. Такие изменения вносятся с помощью методов setPosition() и setSalary(). Правда, сейчас они неправильно работают. Разберись, в чем причин

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