Вложенные классы — это классы, определённые внутри другого класса. Они бывают:
Пример анонимного класса:
Button b = new Button(); b.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // действие при нажатии } });
Особенности:
Может ли внутренний (non-static inner) класс содержать статические методы или переменные?
Ответ: Нет, не может, кроме констант (static final). Только static nested class (статический вложенный класс) может иметь static-члены.
Пример (ошибка):
class Outer { class Inner { static int x = 10; // Ошибка компиляции! } }
Правильно будет так:
class Outer { static class StaticNested { static int x = 10; // OK } }
История
В Android-приложении использовали inner class как обработчик событий. Обработчик хранился в static-поле и держал неявную ссылку на Activity, из-за чего при её уничтожении происходила утечка памяти, а приложение начинало "течь", вплоть до OutOfMemoryError.
История
В одном из микросервисов использовали анонимные классы, ссылающиеся на внешние переменные-итераторы. После рефакторинга переменные перестали быть effectively final, а код перестал компилироваться — разработчики долго искали причину, пока не вспомнили про это ограничение.
История
В библиотеке использовали статические переменные внутри inner class, думая, что это обычная практика. В новых версиях JDK проект перестал компилироваться, поскольку стандарт стал строже следовать ограничениям. Понадобилась срочная переработка архитектуры.