Klasy zagnieżdżone to klasy zdefiniowane wewnątrz innej klasy. Mogą być:
Przykład klasy anonimowej:
Button b = new Button(); b.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // działanie po naciśnięciu } });
Cechy:
Czy wewnętrzna (non-static inner) klasa może zawierać metody lub zmienne statyczne?
Odpowiedź: Nie, nie może, z wyjątkiem stałych (static final). Tylko static nested class (statyczna klasa zagnieżdżona) może mieć człony statyczne.
Przykład (błąd):
class Outer { class Inner { static int x = 10; // Błąd kompilacji! } }
Poprawnie będzie tak:
class Outer { static class StaticNested { static int x = 10; // OK } }
Historia
W aplikacji na Androida użyto inner class jako obsługę zdarzeń. Obsługa była przechowywana w polu static i trzymała niejawne odniesienie do Activity, co spowodowało wyciek pamięci po jej zniszczeniu, a aplikacja zaczęła "przeciekać", aż do OutOfMemoryError.
Historia
W jednym z mikrousług użyto klas anonimowych, które odnosiły się do zewnętrznych zmiennych-iteracyjnych. Po refaktoryzacji zmienne przestały być efektywnie finalne, a kod przestał się kompilować — programiści długo szukali przyczyny, aż przypomnieli sobie o tym ograniczeniu.
Historia
W bibliotece użyto zmiennych statycznych wewnątrz inner class, myśląc, że to powszechna praktyka. W nowych wersjach JDK projekt przestał się kompilować, ponieważ standard stał się bardziej restrykcyjny w przestrzeganiu ograniczeń. Konieczna była pilna przeróbka architektury.