var и вывод типов
var позволяет не писать тип явно — компилятор сам его выводит из значения справа. Это не динамическая типизация, как в Python: тип фиксируется один раз, на этапе компиляции, и дальше переменная ведёт себя как обычно типизированная.
var name = "Артур"; // компилятор знает: это String
var age = 25; // это int
var list = new ArrayList<String>(); // это ArrayList<String>
name = 5; // ❌ ошибка компиляции — name уже String, поменять тип нельзя
var экономит на длинных типах справа и слева одновременно — особенно заметно с дженериками: var list = new ArrayList<String>(); короче, чем ArrayList<String> list = new ArrayList<String>();.
Копнуть глубже
Где var нельзя использовать:
- Поля класса — только локальные переменные внутри методов;
- Параметры методов — нельзя написать
void foo(var x); - Без инициализатора —
var x;не скомпилируется, типу неоткуда взяться; var x = null;— тоже ошибка,nullсам по себе не несёт информации о типе.
Когда var ухудшает читаемость. Если из правой части не видно тип — лучше написать его явно:
var result = service.process(data); // 😕 что вернёт process? непонятно без IDE
ValidationResult result = service.process(data); // ✅ сразу видно
Правило: var хорош, когда тип очевиден из контекста (new ArrayList<>(), "строка", 5), и не очень — когда он спрятан за вызовом метода с неочевидным именем.
Под капотом
var — чисто синтаксический сахар для компилятора, не для JVM. После компиляции байт-код с var name = "Артур"; и с String name = "Артур"; абсолютно идентичен — компилятор подставляет выведенный тип прямо в .class-файл, и до JVM информация о том, что был использован var, вообще не доходит.
Поэтому var не влияет ни на производительность, ни на безопасность типов в рантайме — это вопрос исключительно того, сколько печатать в исходном коде.
• где `var` нельзя использовать и когда он вредит читаемости (если дошёл до 2-го слоя).