var появился в Java 10. Компилятор смотрит на выражение справа и подставляет его тип, как если бы вы написали его руками. После этого тип не меняется: var x = 1; x = "a"; не скомпилируется. Это не динамическая типизация, как в JavaScript или Python, — просто меньше шума в коде.
Где работает: локальные переменные с инициализатором, переменные в for и for-each, параметры лямбд (с Java 11, удобно для аннотаций).
Где нельзя: поля класса, параметры методов, возвращаемые значения, объявление без инициализатора, инициализация null, лямбда без целевого типа, массив через {1, 2}.
Тонкость: var list = new ArrayList<>(); выведет ArrayList<Object> — ромбовидный оператор без типа даёт Object. И var выводит конкретный тип справа (ArrayList), а не интерфейс (List).
Рекомендация — использовать, когда тип очевиден: var users = new HashMap<String, List<User>>(). Если справа вызов метода с неочевидным результатом — лучше указать тип явно.