Classi annidate – sono classi definite all'interno di un'altra classe. Esse possono essere:
Esempio di classe anonima:
Button b = new Button(); b.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // azione al clic } });
Caratteristiche:
Un inner class (classe interna non statica) può contenere metodi o variabili statiche?
Risposta: No, non può, tranne che per le costanti (static final). Solo la static nested class (classe annidata statica) può avere membri statici.
Esempio (errore):
class Outer { class Inner { static int x = 10; // Errore di compilazione! } }
Sarà corretto così:
class Outer { static class StaticNested { static int x = 10; // OK } }
Storia
In un'app Android hanno usato una classe interna come gestore eventi. Il gestore era memorizzato in un campo statico e conservava un riferimento implicito all'Activity, causando perdite di memoria quando veniva distrutta, e l'applicazione iniziava a "perdere memoria", fino a provocare OutOfMemoryError.
Storia
In uno dei microservizi hanno usato classi anonime che facevano riferimento a variabili iteratore esterne. Dopo la refactoring, le variabili hanno smesso di essere effettivamente final, e il codice ha smesso di compilare — gli sviluppatori hanno cercato a lungo la causa, finché non si sono ricordati di questa limitazione.
Storia
Nella libreria hanno usato variabili statiche all'interno di una classe interna, pensando che fosse pratica comune. Nelle nuove versioni di JDK, il progetto ha smesso di compilare, poiché lo standard ha cominciato a seguire più rigorosamente le restrizioni. È stata necessaria una riprogettazione urgente dell'architettura.