Ключевое отличие
Выбор между статическими и нестатическими внутренними классами зависит от того, нужен ли внутреннему классу доступ к членам экземпляра внешнего класса.
- Нестатические внутренние классы хранят неявную ссылку на экземпляр своего внешнего класса
- Статические вложенные классы не держат эту ссылку
Когда использовать нестатические внутренние классы
Используй нестатические внутренние классы, когда:
- Внутреннему классу нужен доступ к полям или методам экземпляра внешнего класса
- Ты реализуешь обработчики событий или коллбэки, которые зависят от состояния внешнего класса
- Жизненный цикл внутреннего класса связан с экземпляром внешнего класса
Когда использовать статические вложенные классы
Используй статические вложенные классы, когда:
- Внутреннему классу не нужен доступ к членам внешнего класса
- Экземпляры вложенного класса будут существовать дольше экземпляров внешнего класса
- Ты хочешь избежать утечек памяти, вызванных ненужными ссылками
- Тебе нужно более простое создание экземпляров через reflection
- Ты хочешь улучшить производительность, снизив расходы на память
Особенности памяти и производительности
Каждый экземпляр нестатического внутреннего класса несёт скрытую ссылку на свой внешний класс. Это создаёт несколько проблем:
- Повышенное потребление памяти на один экземпляр
- Потенциальные утечки памяти, если экземпляры внутреннего класса остаются в памяти после того, как внешний класс удалён сборщиком мусора
- Дополнительная сложность при использовании reflection для создания экземпляров класса
Лучшая практика
По умолчанию предпочитай статические вложенные классы, если у тебя нет конкретной причины обращаться к членам экземпляра внешнего класса. Такой подход чище, производительнее и предотвращает тонкие ошибки, связанные с памятью.