var: Удобный сахар или скрытая угроза?С выходом Java 10 ключевое слово
var позволило нам писать меньше кода. var - это Local Variable Type Inference. Это значит, что Java осталась строго типизированным языком, просто теперь компилятор сам догадывается о типе переменной, глядя на то, что находится справа от знака равно (=).Но иногда его догадки могут вас удивить. Вот 3 примера, где
var работает неочевидно.1. Ловушка "Diamond Operator" (
<>)Самая частая ошибка новичков.
// Без var (Классика)
List<String> list = new ArrayList<>();
// Компилятор видит слева List<String> и понимает, что справа тоже String.
// С var (Ошибка)
var list = new ArrayList<>();
В чем проблема?
У компилятора нет информации о типе. Он видит пустые скобки
<> и решает, что это ArrayList<Object>.В итоге вы теряете типизацию:
list.add("Hello");
list.add(123); // ✅ Это сработает, хотя вы, вероятно, хотели только строки!
✅ Как исправить:
Если используете
var с конструктором, всегда указывайте тип справа:
var list = new ArrayList<String>();
2. Магия "Пересечения типов" (Intersection Types)
А вот это уже высший пилотаж, который часто встречается при использовании
List.of() или Map.of().Что будет, если сложить в список данные разных типов?
var magicList = List.of(10, 20.5, "30");
// Какой тут тип списка? List<Object>?
На самом деле компилятор выведет наиболее специфичный общий тип.
Тип переменной
magicList будет выглядеть примерно так:List<? extends Serializable & Comparable<? extends Serializable & Comparable<?>>>Java находит общие интерфейсы для
Integer, Double и String (все они реализуют Serializable и Comparable) и создает этот ужасный тип-франкенштейн. Это работает, но может свести с ума вашу IDE или методы, принимающие конкретные типы.3. Анонимные классы на стероидах
var позволяет делать трюк, невозможный ранее: сохранять тип анонимного класса.
var user = new Object() {
String name = "Alex";
int age = 25;
};
// Это работает!
System.out.println(user.name);
System.out.println(user.age);
Если бы мы написали
Object user = ..., поля name и age были бы недоступны. А var "видит" реальную структуру анонимного объекта. Это иногда полезно для локальных промежуточных вычислений, заменяя DTO или кортежи.🧠 Золотое правило использования
var хорош тогда, когда тип очевиден из правой части:🔴👍
var users = Map.of("id", 1); (Понятно, что это Map)🔴👍
var stream = list.stream(); (Понятно, что Stream)🔴👎
var result = service.process(); (Что вернулось? boolean? User? null?)Читаемость кода важнее краткости!
📲 Мы в MAX
👉 @java_geek