Что такое анонимный класс в Java
Что проверяют
Понимаете ли вы, что анонимный класс это отдельный класс со своим экземпляром и своими связями, а не просто короткая запись. Второй слой вопроса почти всегда про сравнение с лямбдой.
Как отвечать
Анонимный класс объявляется и создаётся одним выражением: он либо реализует один интерфейс, либо наследует один класс, собственного имени у него нет.
Comparator<String> byLength = new Comparator<>() {
@Override
public int compare(String a, String b) {
return Integer.compare(a.length(), b.length());
}
};Что важно проговорить. Своего конструктора у него быть не может, начальную настройку делают блоком инициализации. Захваченные локальные переменные обязаны быть фактически финальными. В нестатическом контексте экземпляр держит неявную ссылку на внешний объект, а this внутри указывает на сам анонимный класс, до внешнего добираются через уточнение именем внешнего класса. Компилятор выпускает для него отдельный файл класса с номером в имени.
Сравнение с лямбдой: лямбда годится только для интерфейса с одним абстрактным методом, отдельного класса при компиляции не создаёт и своей области видимости не вводит, поэтому this в ней это внешний объект. Анонимный класс нужен там, где методов несколько, требуется собственное состояние или надо переопределить поведение обычного класса.
Где спотыкаются
Говорят, что анонимный класс и лямбда это одно и то же с разным синтаксисом. Разное значение this и разное количество классов в сборке проверяются первым же уточняющим вопросом.
Не видят удержания внешнего объекта. Анонимный слушатель, отданный в долгоживущий компонент, не даёт сборщику мусора освободить внешний объект целиком, со всеми его полями, и это классический источник утечек.
Используют приём с двойными фигурными скобками для короткого создания коллекции. Каждый такой вызов порождает новый подкласс и ссылку на внешний объект ради экономии пары строк, а заодно ломает сериализацию такой коллекции.