Для понимания языка Java, очень важно понимать его синтаксис. Один из его ключевых, фундаментальных кирпичиков это переменные. Если коротко: переменная это именованная ячейка памяти, в которой лежит значение определенного типа. Объявляется она как тип имя = значение;, например int x = 9;. По месту объявления переменные делятся на переменные объекта, локальные и переменные класса (статические), а переменная с модификатором final это константа, значение которой изменить нельзя.

Кратко

  • Переменная это контейнер с именем и типом. int x = 9; объявляет переменную типа int с именем x и значением 9; полная форма это int x; и потом x = 9;.
  • Тип задается один раз при объявлении, дальше переменную только перезаписывают: x = 4;, x = y + 5;, x += 6;.
  • Три вида по месту объявления: переменные объекта (в классе, вне методов), локальные (внутри метода, конструктора или блока) и переменные класса (со словом static).
  • Поля объекта и класса получают значение по умолчанию (0, false, null), а локальная переменная нет: пока в нее ничего не положили, компилятор не даст ее прочитать.
  • Константа это переменная с модификатором final: значение задается один раз, а имя пишут БОЛЬШИМИ_БУКВАМИ через подчеркивание.
  • Имена переменных пишут в lowerCamelCase: countOfPeople. С Java 10 тип локальной переменной можно не писать вовсе: var x = 9;.

Что такое переменная в Java

Переменная в Java это контейнер, в котором может храниться некоторое значение данных для дальнейшего использования в программе. По сути переменная это минимальная неделимая единица Java-приложения. Переменные в Java бывают двух видов: предназначенные для маленьких данных (примитивные переменные) и для более сложных, тяжелых (ссылочные переменные). Сегодня мы рассмотрим первый случай, когда переменные хранят именно само значение данных. Такие переменные называют примитивными. Четыре кота сидят в отдельных ячейках большой картонной коробки-сетки, как значения в своих переменных

Объявление переменных в Java

Давайте рассмотрим такой пример:

int x = 9;
Разберем, что мы видим:
  • int: тип переменной, описывающий целые числа в промежутке от -2147483648 до 2147483647;
  • x: имя переменной (нам же нужно их отличать между собой, верно?);
  • =: знак присваивания переменной какого-то значения;
  • 9: ее непосредственное значение;
  • ;: конец данной команды.
А теперь соберем все вместе: мы задаем, что переменная типа int, с именем x имеет значение 9. Данный пример имеет сокращенную форму записи, полная выглядит так:

int x; 
x = 9;
В первой строке мы видим объявление переменной с присвоением ей имени, то есть этим мы говорим JVM выделить место под переменную int (4 байта) и задать ей имя x. Во второй мы задаем ей значение 9. Если такая переменная объявлена как поле класса, то до этого у нее было значение по умолчанию, а именно 0. А вот у локальной переменной внутри метода значения по умолчанию нет: пока вы ничего в нее не положили, компилятор не даст ее прочитать (это правило из спецификации языка, раздел 4.12.5). Стоит сказать пару слов об именовании переменных. Как правило они пишутся в нижнем верблюжьем стиле. То есть, например, если у нас есть переменная, описывающая количество людей (count of people), подходящее для нее имя будет:

int countOfPeople;
В этом названии первое слово начинается со строчной (маленькой) буквы, а каждое следующее с заглавной (большой). Это делается для удобства чтения таких имен, так как обычно имена переменных состоят из более чем одного слова.

Переопределение переменных

Вернемся к нашему примеру с объявлением переменной:

int x = 9;
Если мы однажды положили в переменную какое-то значение, это не значит, что во время выполнения программы переменная x всегда будет иметь значение 9. Мы можем ее перезаписать:

x = 4;
Все почти так же, но мы уже не добавляем тип (int), ведь он прописан при объявлении переменной (объявлении о ее существовании). Далее мы только ее переиспользуем, как к примеру здесь мы видим ее перезапись (задаем нашей переменной новое значение, затирая старое). Предположим, что у нас еще появилась переменная:

int y = 7;
И задав: x = y; Старое значение переменной x будет удалено, перезаписавшись копией значения y, а именно 7. Также можно задать значение какой-то другой переменной, увеличенное на нужное нам число:

x = y + 5;
Так как у нас переменная y была равна 7, в результате x будет равен 12. Более интересна возможность выполнить данные действия:

x = x + 6;
Что мы здесь видим? Переменной x задается значение, равное прошлому, увеличенному на 6, то есть это будет: 12 + 6 = 18. Эту же запись можно сократить, не повторяя x дважды:

x += 6;
Обратите внимание на порядок знаков. += означает «прибавить и присвоить», и в x окажется 18. Если же случайно написать x =+ 6, компилятор прочитает это как обычное присваивание положительного числа 6, и вместо 18 в x окажется 6. По спецификации запись x += 6 равносильна x = x + 6, только x вычисляется один раз.

Виды переменных

Все, что ниже, относится и к примитивным, и к ссылочным переменным: деление по месту объявления от типа не зависит. Приложение в Java состоит из классов и объектов. Рассмотрим, какими бывают Java переменные:
  • переменные объекта;
  • локальные переменные;
  • переменные класса.
Крупный план чихуахуа с прищуренными глазами и довольным выражением на руках у хозяйкиВ качестве класса-примера мы возьмем класс собаки с методом “лаять”:

public class Dog {
   public void bark() {
   }
}

Переменные объекта

Переменные объявляются в классе, но при этом не в методе, конструкторе или блоке.

public class Dog {
public  int value = 9;
   public void bark() {
   }
}
Чтобы обратиться к этой переменной, нам нужно для начала создать объект:

Dog dog = new Dog();
System.out.println(dog.value);
Переменные создаются лишь после того, как будет создан объект (то есть после создания объекта с помощью new). В объекте внутренние переменные всегда видимы для всех методов, конструктора или чего-либо внутри этого же объекта. Как говорилось выше, у переменных объекта существуют значения по умолчанию. Для числа значение по умолчанию равно 0, для символов (char) это символ с кодом 0, то есть '\u0000', для логических (boolean) это false, для ссылок на объект это null. Подробнее о том, как поля получают начальные значения, в отдельной статье.

Локальные переменные

Данные переменные объявляются в методах, конструкторах или блоках.

public class Dog {
   public void bark() {
   int value = 9;
   }
}
Локальные переменные существуют только в вызванном блоке кода, при окончании которого они удаляются из памяти. Они видимы лишь в пределах объявленного метода, конструктора или блока. То есть использовать переменную, например, в другом методе нельзя. Модификаторы доступа нельзя использовать для локальных переменных. Какой в них смысл, если дальше границ метода переменную не видно? Данный вид переменных создается, когда метод (или конструктор, или блок) вызывается, и уничтожается после завершения. И еще одно важное отличие от переменных объекта: значения по умолчанию у локальной переменной нет. Если написать int value; и попытаться вывести value, не присвоив ничего, компилятор откажется собирать программу с ошибкой «variable value might not have been initialized». С Java 10 у локальных переменных есть и вторая форма объявления, через слово var: var value = 9;. Это не «переменная без типа»: компилятор выводит тип из правой части (здесь int) и дальше следит за ним так же строго. Работает var только для локальных переменных с инициализатором; для полей класса и параметров методов его использовать нельзя (JEP 286).

Переменные класса

Данный вид переменных еще называют статическими. Они объявляются со словом-модификатором static, но за пределами метода, конструктора или блока.

public class Dog {
public static  int value = 9;
   public void bark() {
   }
}
Обращаемся к нашей переменной:

System.out.println(Dog.value);
Где Dog это имя класса, к которому прикреплена переменная. Значение по умолчанию такое же, как и у переменных объекта. Для чисел по умолчанию это 0, для char это '\u0000', для boolean это false, для ссылок на объект это null. Статическая переменная всегда одна, независимо от того, сколько объектов создано из класса, ведь она крепится только к классу. Переменные класса создаются при первой загрузке класса в JVM и живут до завершения программы.

Три вида переменных рядом

Чтобы различия не расползались по трем разделам, соберем их в одну таблицу:
Переменная объекта Локальная переменная Переменная класса
Где объявляется в классе, вне методов в методе, конструкторе или блоке в классе, со словом static
Когда создается при создании объекта через new при входе в метод или блок при первой загрузке класса в JVM
Значение по умолчанию есть: 0, '\u0000', false, null нет, нужно присвоить до чтения есть: 0, '\u0000', false, null
Как обратиться dog.value, через объект по имени внутри метода Dog.value, через класс
Сколько экземпляров по одной на каждый объект по одной на каждый вызов метода одна на весь класс
Модификаторы доступа можно нельзя можно
Статические переменные в Java часто используются, когда объявляются как константы. О них поговорим подробнее.

Что такое константы в Java

Константа это заданное, фиксированное значение, которое не должно меняться. А что такое константы в программировании? Это некоторое постоянное значение, которое известно до начала работы приложения, при этом оно задается в коде один раз. В Java константы это переменные, обозначенные специальным словом final. Как правило, их объявляют еще и со словом static, чтобы значение было одно на весь класс, а не копировалось в каждый объект:

static final int VALUE = 54;
Здесь мы получаем переменную, которую нельзя изменить после задания ей какого-либо значения. Дело в том, что константы гораздо проще, чем переменные. Они всегда однозначно определены и никогда не меняются. Немного выше мы говорили об именовании переменных, и нам стоит уделить внимание и особенностям именования констант. В константных переменных все слова пишутся БОЛЬШИМИ буквами, разделяемыми с помощью знака подчеркивания _. Например, нам нужна константа, описывающая максимальное значение для чего-либо:

static final int MAX_VALUE = 999;

Подведем итоги

  • Переменная предоставляется нам как место хранения наших данных (или адрес места), что позволяет управлять приложением.
  • У переменных примитивного типа есть определенный формат данных, размер, диапазон значений, которые могут храниться в памяти.
  • Переменные можно разделять по местонахождению: переменные объекта, локальные, класса.
  • Существует особый вид переменных, константы: их значение задается один раз и не меняется. Объявленные как public static final поля класса, они доступны из любого места программы.

Вопросы и ответы

Чем переменная объекта отличается от переменной класса?

Количеством копий. Переменная объекта живет внутри каждого созданного объекта: у ста собак сто своих value. Переменная класса объявлена со словом static и существует в одном экземпляре на весь класс, сколько бы объектов ни было; обращаются к ней через имя класса, Dog.value, даже если ни одной собаки еще не создано.

Какое значение у переменной, если ничего не присвоить?

Зависит от того, где она объявлена. Поле объекта или класса получает значение по умолчанию: 0 для чисел, false для boolean, null для ссылок. Локальная переменная внутри метода значения по умолчанию не получает, и читать ее до присваивания нельзя: это ошибка компиляции, а не мусор в памяти.

Почему компилятор пишет «variable might not have been initialized»?

Потому что вы читаете локальную переменную, в которую ни на одном пути выполнения ничего не положили. Java требует, чтобы локальная переменная была точно присвоена до первого использования, и проверяет это на этапе компиляции. Лечится присваиванием при объявлении: int count = 0; вместо int count;.

Чем x += 6 отличается от x = x + 6 и от x =+ 6?

x += 6 и x = x + 6 дают один результат: к текущему значению прибавляется 6. Разница только в том, что в первой записи x вычисляется один раз. А вот x =+ 6 это ловушка: знаки стоят в другом порядке, и компилятор читает это как x = (+6), то есть просто кладет в x шестерку. Ошибки не будет, будет неверный результат.

Как объявить константу в Java и почему ее пишут большими буквами?

Модификатором final: static final int MAX_VALUE = 999;. После первого присваивания изменить такую переменную нельзя, компилятор не позволит. Чаще всего константы делают еще и static, чтобы значение было одно на весь класс. БОЛЬШИЕ_БУКВЫ с подчеркиванием это соглашение об именовании: по имени сразу видно, что перед вами константа, а не обычная переменная.

Что такое var и когда его использовать?

Способ объявить локальную переменную, не указывая тип явно: var x = 9;. Появился в Java 10. Тип при этом никуда не делся, компилятор выводит его из правой части и дальше проверяет как обычно. Использовать var стоит там, где тип и так очевиден из инициализатора; для полей класса, параметров методов и переменных без начального значения он не работает.

Читайте также