W3docs

Переменные в Java

Объявляйте и инициализируйте переменные в Java, изучайте виды переменных (локальные, экземпляра, статические) и правила именования.

Переменная — это именованная ячейка памяти с фиксированным типом. После объявления тип изменить нельзя, но хранящееся значение, как правило, можно. Тип определяет, сколько памяти занимает переменная, какие значения допустимы и какие операции разрешает компилятор. В этой главе рассматривается, как объявлять и инициализировать переменные, какие четыре разновидности различает Java, а также правила использования final, var и области видимости.

Объявление переменной

Базовая форма — тип, затем имя и точка с запятой:

type name;

Например, int score; резервирует слот типа int с именем score. Тип — один из встроенных типов Java (int, double, boolean, char, …) или любой класс или интерфейс — полный список см. в разделе Java Data Types.

Простейшие объявления:

int score;
String name;
boolean ready;

Они резервируют память, но пока не помещают туда никакого значения.

Инициализация

Для присваивания значения используется =:

int score = 0;
String name = "Ada";
boolean ready = true;

Можно также объявить и присвоить по отдельности:

int score;
score = 0;

Или объявить несколько переменных одного типа сразу:

int x = 1, y = 2, z = 3;

(Обычно нагляднее писать по одной переменной на строку.)

Локальные переменные должны быть присвоены перед использованием

Локальная переменная — объявленная внутри метода — не имеет значения по умолчанию. Компилятор запрещает её читать до тех пор, пока ей не будет что-то присвоено:

public static void main(String[] args) {
    int x;
    // System.out.println(x); // compile error: variable x might not have been initialized
    x = 5;
    System.out.println(x);    // OK
}

Это одна из самых полезных функций безопасности Java — она предотвращает целый класс ошибок, которые в других языках остались бы незамеченными.

Четыре разновидности переменных

Java различает четыре категории переменных по месту их объявления:

  1. Локальные переменные — объявляются внутри метода или блока. Существуют только во время выполнения метода. Значения по умолчанию нет. Перед использованием должны быть инициализированы.
  2. Переменные экземпляра (поля) — объявляются внутри класса, но вне методов. По одной копии на каждый объект. По умолчанию равны 0 / 0.0 / false / null.
  3. Статические переменные (переменные класса) — объявляются с ключевым словом static. Одна копия, общая для всех экземпляров класса. По умолчанию равны 0 / false / null.
  4. Параметры — объявляются в сигнатуре метода; получают значение, переданное вызывающим кодом.
public class Counter {
    static int totalCounters;   // static (class) variable
    int count;                  // instance variable

    public void add(int delta) { // delta is a parameter
        int doubled = delta * 2; // doubled is a local variable
        count += doubled;
    }
}

С переменными экземпляра и статическими переменными вы подробнее познакомитесь в главах об ООП; пока большинство переменных, с которыми вы будете работать, будут локальными.

final — присвоить один раз

Ключевое слово final перед объявлением делает переменную однократно присваиваемой. После первого присваивания изменить значение нельзя:

final int MAX_RETRIES = 3;
// MAX_RETRIES = 4; // compile error: cannot assign a value to final variable

Использование final для значений, которые не должны меняться, делает намерение явным и позволяет компилятору обнаруживать случайное переприсваивание. По соглашению, final-поля с фиксированными константами именуются в стиле UPPER_SNAKE_CASE (см. Java Naming Conventions).

Обратите внимание: final фиксирует ссылку, а не объект, на который она указывает. final-ссылку переназначить нельзя, но сам объект по-прежнему может изменяться:

final int[] nums = {1, 2, 3};
nums[0] = 99;        // OK — the array contents change
// nums = new int[5]; // compile error — the reference is final

var — пусть компилятор выведет тип

Начиная с Java 10, можно писать var вместо типа для локальных переменных, когда тип очевиден из правой части выражения:

var name = "Ada";          // inferred as String
var score = 0;             // inferred as int
var values = new int[10];  // inferred as int[]

var — это не динамическая типизация: переменная по-прежнему имеет фиксированный тип, просто компилятор определяет его сам. Ограничения:

  • Только для локальных переменных.
  • Правая часть должна присутствовать (var x; недопустимо).
  • Нельзя использовать для параметров, переменных экземпляра и статических переменных.

var особенно удобен, когда имя типа длинное или очевидно из контекста:

var orders = new HashMap<String, List<Order>>();

Используйте обычные объявления типов, когда выводимый тип может быть неочевиден читателю кода.

Область видимости

Переменная находится в области видимости — доступна — от места объявления до конца охватывающего блока:

public static void main(String[] args) {
    int outer = 1;

    if (outer > 0) {
        int inner = 2;
        System.out.println(outer + inner);   // both visible
    }

    // System.out.println(inner);   // compile error: inner is out of scope
}

Нельзя объявить две локальные переменные с одинаковым именем в перекрывающихся областях видимости — но имя может использоваться повторно в двух отдельных, непересекающихся блоках:

for (int i = 0; i < 3; i++) { /* i lives here */ }
for (int i = 0; i < 5; i++) { /* a new, separate i */ }  // fine

Хорошая практика — делать область видимости переменных как можно меньше: объявляйте каждую переменную как можно ближе к месту первого использования.

Рабочий пример

java— editable, runs on the server

Что дальше

Раздел Java Naming Conventions охватывает стандартные правила именования классов, методов, переменных и констант, которым следуют все Java-проекты.

Практика

Практика
Какое утверждение о переменных Java верно?
Какое утверждение о переменных Java верно?
Was this page helpful?