Перейти к содержимому
Теория · Переменные и типы · урок 7 из 8

Значения по умолчанию

Что лежит в коробке, в которую ещё ничего не положили? В первом уроке темы компилятор не дал прочитать такую переменную внутри main. Но у переменных, объявленных прямо в классе, ответ другой.

Представьте две коробки. Одну вы завели сами и пока ничего в неё не положили, поэтому заглядывать в неё компилятор не разрешает. Другую заранее приготовил склад, и в ней уже лежит стандартная вещь: ноль, false или пометка «ничего». Посмотрим на вторую коробку в деле:

JAVA
public class Main {
    static int count;
    static double price;
    static boolean ready;
    static String name;

    public static void main(String[] args) {
        System.out.println(count); // 0
        System.out.println(price); // 0.0
        System.out.println(ready); // false
        System.out.println(name);  // null
    }
}

Программа компилируется и печатает четыре значения, хотя ни одной из четырёх переменных значение не задали.

Поля и значения по умолчанию

Переменную, объявленную прямо в классе, вне main, называют полем. Слово static перед ним — как у main: поле принадлежит самому классу. Константа вроде static final int MAX_SPEED = 120; — тоже поле, только её значение задано сразу и не меняется.

Поле без значения получает значение по умолчанию своего типа:

Тип поляЗначение по умолчанию
byte, short, int, long0
float, double0.0
charсимвол с кодом 0, '\u0000'
booleanfalse
Stringnull

Давайте разберём вывод программы:

  1. count печатается как 0, как любое целое поле без значения.
  2. price печатается как 0.0, с точкой, потому что это double.
  3. ready печатается как false.
  4. name печатается как null.

null — особое значение «ничего». Это не пустая строка: строки в поле name нет вовсе, и println сообщает об этом словом null.

Здесь картинка с коробкой неточна. Пустая коробка в жизни — это «ничего». А поле типа int не пусто: в нём лежит настоящее число 0, и с ним можно работать, как с любым другим.

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

Переменную, объявленную внутри main или другого метода, называют локальной. Значения по умолчанию она не получает. Сравним поле и локальную переменную в одной программе:

JAVA
public class Main {
    static int total;

    public static void main(String[] args) {
        int local;
        System.out.println(total); // 0
        local = 7;
        System.out.println(local); // 7
    }
}

Разберём по строкам:

  1. static int total; объявляет поле, и в нём сразу лежит 0.
  2. int local; объявляет локальную переменную без значения.
  3. System.out.println(total) печатает 0: поле можно читать сразу.
  4. local = 7; кладёт значение в локальную переменную.
  5. System.out.println(local) печатает 7. Без строки local = 7; программа бы не скомпилировалась.

Почему поле получает значение само, а локальная переменная — нет? Это частый вопрос на собеседовании. Ответ такой:

  • локальную переменную видно только внутри её метода, поэтому компилятор может проверить каждое чтение и поймать забытое значение ещё до запуска;
  • поле могут читать разные методы класса в любом порядке, поэтому JVM сама кладёт в каждое поле значение по умолчанию, когда загружает класс.

Частая ошибка

Поле объявили без static:

JAVA
public class Main {
    int count;

    public static void main(String[] args) {
        System.out.println(count); // ✗
    }
}
TEXT
error: non-static variable count cannot be referenced from a static context

Программа не компилируется. Поле без static принадлежит не классу, а объекту — отдельной вещи, которую программа создаёт по описанию класса уже во время работы. В этой программе объектов никто не создавал, и main работает без них, поэтому прочитать такое поле не может. Пока пишите у полей static, как у самого main: static int count;.

Главное

  • Поле — переменная, объявленная в классе вне main; без значения оно получает значение по умолчанию: 0, 0.0, false или null.
  • Локальная переменная значения по умолчанию не получает, и компилятор не даст прочитать её до первого присваивания.
  • null в поле типа String значит, что строки там нет.
  • Поле, которое читает main, объявляют со словом static.