Что такое переменная
Переменная — это именованный ящик, который хранит значение. В Java у каждой переменной есть фиксированный тип — он определяется при объявлении — и этот тип никогда не меняется. Именно это делает Java статически типизированным языком: компилятор знает тип каждой переменной ещё до запуска программы и откажется компилировать код, который кладёт в ящик значение неподходящего типа.
Объявление состоит из трёх частей: типа, имени и (обычно) начального значения.
Читайте int age = 30; как «создай int по имени age и положи в него 30». Точка с запятой завершает инструкцию — точно так же, как, согласно странице о комментариях, это делает любая инструкция.
Объявить сейчас, присвоить позже
Вы можете отделить объявление от первого присваивания. Тип указывается один раз, при объявлении; после этого вы присваиваете, используя только имя и =:
Правило, на котором спотыкаются новички: вы должны присвоить значение локальной переменной, прежде чем её читать. Компилятор это отслеживает и отклоняет код, который читает неинициализированную локальную переменную:
int score;
System.out.println(score); // compile error: variable score might not have been initialized
Это не помеха, а особенность языка — она ловит целый класс ошибок ещё до того, как программа запустится.
Правила и соглашения именования
Java навязывает несколько жёстких правил, а поверх них накладывает соглашения. Правила: имя может содержать буквы, цифры, _ и $, но не может начинаться с цифры, не может быть зарезервированным ключевым словом (таким как int или class) и чувствительно к регистру (age и Age — две разные переменные).
Соглашения, которым следуют все:
- Переменные и методы используют
camelCase:firstName,totalScore. - Константы используют
UPPER_SNAKE_CASE:MAX_USERS. - Имена должны описывать значение:
count, а неc;userEmail, а неx.
Понятные имена — это не украшение, а то, как ваше будущее «я» читает код. totalPrice = itemCount * pricePerItem говорит само за себя так, как t = c * p не сможет никогда.
Типобезопасность: ящик сохраняет свой тип
Поскольку тип закрепляется при объявлении, вы не можете положить в переменную значение неподходящего типа. Это ловит ошибки на этапе компиляции:
int age = 30;
age = "thirty"; // compile error: incompatible types - String cannot become int
Присваивание между числовыми типами подчиняется правилам расширения (widening) — меньший тип автоматически перетекает в больший, но не наоборот. Подробно мы разберём это на страницах о типах данных и приведении типов; пока просто помните, что компилятор за всем следит.
Ключевое слово var
Начиная с Java 10, вы можете написать var вместо типа и позволить компилятору вывести его из значения справа:
var — это не динамическая типизация: name остаётся таким же String, как если бы вы написали String name, и вы по-прежнему не сможете позже присвоить ему int. Он лишь экономит набор текста. Подвох: для вывода типа var нужен инициализатор, поэтому var x; недопустимо, и он работает только для локальных переменных — никогда для полей, параметров методов или возвращаемых типов. Используйте его там, где тип очевиден из правой части; пишите тип явно, когда это добавляет ясности.
Константы с final
Когда значение не должно меняться после установки, пометьте его как final. Любая попытка переприсвоить его становится ошибкой компиляции:
final выражает намерение («это фиксированное значение») и позволяет компилятору защитить его за вас. Прибегайте к нему всякий раз, когда значение концептуально является константой — ставки, лимиты, ключи конфигурации, — чтобы случайное переприсваивание было поймано, а не молча отправилось в продакшн как баг.
Область видимости переменных
Переменная существует только внутри блока — { ... } —, в котором она объявлена, и умирает на закрывающей фигурной скобке. Это её область видимости. Переменная, объявленная внутри цикла или блока if, невидима за его пределами:
И i, и square принадлежат циклу и исчезают, когда он заканчивается; total объявлена во внешнем блоке, поэтому она сохраняется. Практический вывод: объявляйте каждую переменную в наименьшем блоке, которому она нужна. Узкая область видимости означает меньше имён, борющихся за ваше внимание, и меньше шансов неправильно использовать значение вдали от того места, где оно было задано.
Далее: типы данных
Каждая переменная на этой странице начиналась с типа — int, double, String, boolean. Следующая страница подробно разбирает типы данных Java: восемь примитивов, размер каждого из них, разницу между примитивами и объектами и какой тип выбрать в той или иной ситуации.
Часто задаваемые вопросы
Как объявить переменную в Java?
Напишите тип, затем имя и при желании присвойте значение: int age = 30;. Тип (int) фиксирован на всё время жизни переменной; имя (age) — это то, как вы к ней обращаетесь. Вы можете разбить это на объявление и последующее присваивание — int age; age = 30; —, но локальной переменной необходимо присвоить значение, прежде чем её читать.
Что такое ключевое слово var в Java?
Начиная с Java 10, var позволяет компилятору вывести тип локальной переменной из присваиваемого значения: var name = "Ada"; делает name объектом String. Типизация по-прежнему статическая — тип фиксируется на этапе компиляции, он не динамический. var работает только для локальных переменных с инициализатором, но никогда для полей, параметров или объявления без инициализации.
Как создать константу в Java?
Добавьте ключевое слово final: final double PI = 3.14159;. После присваивания переменную final нельзя переприсвоить — компилятор отклоняет любую такую попытку. По соглашению константы пишут в UPPER_SNAKE_CASE, чтобы они выделялись среди обычных переменных.