Константы
Фрагмент лекции JavaRush - университета.
— Знаешь ли ты, Амиго, что не все переменные в Java можно изменять?
— Это как, Ким? Ведь даже само название “переменные” говорит об изменении.
— Ещё как уверена. Во многих языках программирования, в том числе и в Java, есть константы, то есть переменные, значения которых нельзя изменять. И само название “константа” говорит о постоянстве.
— И для чего они нужны?
— Обычно это какие-то фундаментальные вещи наподобие числа Pi
или количества дней в месяцах. Хотя в принципе программист может сделать любую переменную константой, если решит, что это необходимо.
— Например, имя, или цвет машины, или название дня недели?
— Правильно мыслишь. Всё, что не нужно менять.
— И как эти константы выглядят в Java?
— Для них в Java есть специальное ключевое слово — final
. Выглядит создание неизменяемой переменной так же, как и создание обычной, только перед типом переменной нужно написать слово final
:
final тип имя = значение;
— А что, если после создания такой константы попытаться присвоить ей другое значение?
— Правильный вопрос! А правильный ответ на него такой: если ты попробуешь присвоить final
-переменной другое значение, твоя программа просто не скомпилируется.
— А если объявить final
-переменную, но не присвоить ей значение?
— В этом нет смысла, поэтому так поступать в Java тоже запретили. final
-переменную обязательно нужно инициализировать при объявлении, то есть присваивать ей значение. У этого правила есть одно исключение: можно перенести инициализацию переменной класса в конструктор. Но об этом ты узнаешь позже.
— Но не всё то константа, что final
. Чтобы уменьшить количество ключевых слов, разработчики Java используют слово final
не только для объявления констант. final
также может быть указан перед методом и даже классом. Методы, объявленные как final
, нельзя переопределять (override), а от класса, объявленного как final
, нельзя наследоваться.
— Эмм… Переопределять? Наследоваться? Это ты на каком языке сейчас говоришь?
— На языке объектно-ориентированного программирования. Совсем скоро ты вплотную к нему приступишь. А пока просто насладись красивыми терминами.
— Хорошо. Получается, final
можно добавлять перед переменными, классами и методами, и это слово делает их в каком-то смысле неизменными?
— Да. Кроме того, модификатор final
можно добавлять перед любыми переменными: локальными, параметрами, полями класса и статическими переменными.
— Запомни важную вещь: final
перед именем переменной — это всего лишь защита от изменения переменной. Если переменная хранит ссылку на объект, объект все-таки менять можно.
— Не совсем понял.
— Сейчас поймешь. Вот тебе пример:
|
Создаем массив. Так нельзя: переменная 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;
}
Затенение переменных
— Как я уже говорила раньше, в одном методе нельзя создать несколько локальных переменных с одинаковыми именами. В разных методах — можно.
— Это я знаю!
— Но вот то, чего ты, скорее всего, не знаешь, так это того, что у переменных класса и локальных переменных метода вполне могут быть одинаковые имена.
Пример:
Код | Доступность переменных |
---|---|
|
|
— В методе add
мы объявили локальную переменную sum
, и она до конца действия метода перекрывает (или ещё говорят затеняет) собой переменную класса sum
.
— Хм… Я бы сказал, в каком-то смысле это ожидаемое поведение.
— Но это еще не все. Оказывается, если переменную класса затеняет локальная переменная, в методе все-таки существует способ обратиться к переменной класса. Для этого нужно перед ее именем написать ключевое слово this
:
this.имя
— Вот пример, где конфликт имен успешно решается:
Код | Доступность переменных |
---|---|
|
|
Везде переменные count
и sum
доступны как с ключевым словом this
, так и без него. В тех строках, где локальная переменная sum
затеняет переменную класса sum
, доступ к переменной класса sum
возможен только при использовании this
.
— С этим явно надо попрактиковаться.
— Ещё успеешь.
— А что, если затеняется не просто переменная класса, а статическая переменная класса? К ней же не обратишься через this
?
— Всё верно, через this не получится. Обращаться к ней нужно через имя класса:
ClassName.имя
Пример:
Код | Доступность переменных |
---|---|
|
|
— Обрати внимание: везде статические переменные count
и sum
доступны как с префиксом в виде имени класса Solution
, так и без него. В тех строках, где локальная переменная sum
затеняет переменную класса sum
, доступ к переменной класса sum
возможен только при использовании префикса Solution
.
Фрагмент лекции JavaRush - университета.
Переменные внутри цикла for
— И ещё один маленький, но интересный факт. Есть ещё место, где особенным образом объявляется переменная — это цикл for
. Обычно у цикла for
в круглых скобках объявляется переменная-счетчик. И какова же будет видимость этой переменной? Она ведь не находится в теле цикла — значит, весь метод? Или всё-таки нет?
— Мне уже что-то об этом рассказывали. Я так понял, что переменная, объявленная в заголовке цикла for
, видна только в теле цикла и в заголовке цикла for
.
— Молодец, Амиго. Но всё-таки посмотри на пример для закрепления:
Код | Доступность переменных |
---|---|
|
|
— Получается, я в своём коде могу последовательно написать несколько циклов с переменной-счетчиком с одинаковым именем, и проблем не будет?
Не будет. Вот, посмотри:
Код | Доступность переменных |
---|---|
|
|