Ключевое слово var (Java 10+)
Начиная с Java 10 (JEP 286), в язык введён механизм локального вывода типов (Local Variable Type Inference). Ключевое слово var позволяет объявить локальную переменную без явного указания её типа — компилятор сам выведет тип по правой части выражения.
Важно понимать: var — это не динамическая типизация. Java остаётся строго типизированным языком. Тип переменной фиксируется на этапе компиляции и не может измениться в дальнейшем.
Минимальная версия: Java 10.
Синтаксис
var имяПеременной = выражение;
Правая часть обязана быть выражением, по которому компилятор может определить тип. Поэтому объявление без инициализации запрещено.
Зачем нужно
Сокращает шум в коде, особенно с длинными generic-типами.
Делает код ближе по стилю к Kotlin/Scala/Swift, не нарушая строгой типизации.
Уменьшает повторение типа на обеих сторонах присваивания (DRY).
Примечание
var работает только для локальных переменных внутри методов, циклов и блоков. Для полей класса, параметров методов и возвращаемых значений по-прежнему нужен явный тип.
Пример 1. Базовое использование
public class VarBasic {
public static void main(String[] args) {
var number = 42; // int
var pi = 3.14; // double
var name = "AlashEd"; // String
var flag = true; // boolean
System.out.println(number + " " + pi + " " + name + " " + flag);
}
}
Output:
42 3.14 AlashEd true
Пример 2. Generic-коллекции
import java.util.HashMap;
import java.util.Map;
public class VarCollections {
public static void main(String[] args) {
// Без var:
Map<String, Integer> sensors1 = new HashMap<String, Integer>();
// С var — короче:
var sensors = new HashMap<String, Integer>();
sensors.put("trig", 3);
sensors.put("echo", 7);
sensors.put("servo", 9);
System.out.println("Размер: " + sensors.size());
System.out.println("trig pin: " + sensors.get("trig"));
}
}
Output:
Размер: 3
trig pin: 3
Пример 3. Цикл for
import java.util.List;
public class VarLoop {
public static void main(String[] args) {
var pins = List.of(2, 4, 5, 6, 8, 12);
for (var pin : pins) {
System.out.println("Pin D" + pin);
}
}
}
Output:
Pin D2
Pin D4
Pin D5
Pin D6
Pin D8
Pin D12
Пример 4. try-with-resources
import java.io.BufferedReader;
import java.io.StringReader;
import java.io.IOException;
public class VarTryWith {
public static void main(String[] args) throws IOException {
var text = "L298N\nRCWL-9610A\nSG92R";
try (var reader = new BufferedReader(new StringReader(text))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Компонент: " + line);
}
}
}
}
Output:
Компонент: L298N
Компонент: RCWL-9610A
Компонент: SG92R
Пример 5. Сложный generic-тип
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class VarComplex {
public static void main(String[] args) {
// Без var громоздко:
// Map<String, List<Integer>> kits = new HashMap<String, List<Integer>>();
var kits = new HashMap<String, List<Integer>>();
kits.put("RobotPhobo", new ArrayList<>(List.of(2, 4, 5, 6, 8, 12)));
kits.put("Sensors", new ArrayList<>(List.of(3, 7, 9)));
for (var entry : kits.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
}
}
Output:
RobotPhobo -> [2, 4, 5, 6, 8, 12]
Sensors -> [3, 7, 9]
Пример 6. Что НЕ компилируется
public class VarErrors {
// var field = 10; // ОШИБКА: var нельзя для полей класса
// public void m(var x) { } // ОШИБКА: var нельзя в параметрах
public static void main(String[] args) {
// var x; // ОШИБКА: нужна инициализация
// var y = null; // ОШИБКА: тип null не определим
// var arr = {1, 2, 3}; // ОШИБКА: литерал массива требует типа
// Правильные варианты:
var x = 0;
Object y = null;
var arr = new int[] {1, 2, 3};
System.out.println(x + " " + y + " длина=" + arr.length);
}
}
Output:
0 null длина=3
Подводные камни
Предупреждение
varнельзя использовать для полей класса, параметров и возвращаемых значений.Нельзя объявить без инициализации:
var x;— ошибка.Нельзя
var x = null— компилятор не знает тип.Нельзя
var arr = {1, 2, 3}— нуженnew int[] {...}.Не злоупотребляйте:
var result = doSomething();ухудшает читаемость, если имя метода не отражает тип.При работе с
varиdiamond(<>) можно получитьObjectтам, где вы ожидаете generic:var list = new ArrayList<>();дастArrayList<Object>.
Совет
Используйте var там, где тип очевиден из правой части (например, конструктор) или слишком громоздок. Не используйте, когда тип несёт смысловую нагрузку, отсутствующую в имени.
См. также
Примечание
Материал основан на официальной документации Oracle Java SE (docs.oracle.com/en/java/javase) и спецификации JEP 286 (openjdk.org/jeps/286), распространяемой под лицензией Oracle Free Documentation License. Тексты и примеры написаны заново для AlashEd Wiki.