ProgrammazioneSviluppatore Java

Parla delle caratteristiche chiave del lavoro con classi anonime e classi annidate in Java, così come delle insidie nel loro utilizzo.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Classi annidate – sono classi definite all'interno di un'altra classe. Esse possono essere:

  • Static nested classes – classi annidate statiche; non hanno accesso ai membri non statici della classe esterna senza un'istanza.
  • Inner classes – classi annidate non statiche; hanno accesso a tutti i membri della classe esterna.
  • Classi anonime – classi interne senza nome, dichiarate e create di solito sul posto di utilizzo, spesso quando si lavora con interfacce/classi astratte.

Esempio di classe anonima:

Button b = new Button(); b.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // azione al clic } });

Caratteristiche:

  • Le classi anonime possono riferirsi solo a variabili di ambito esterno final (effettivamente final).
  • Ogni istanza della classe interna conserva implicitamente un riferimento all'istanza della classe esterna.
  • A seconda del tipo (static/inner) possono verificarsi perdite di memoria o dipendenze inaspettate.

Domanda trabocchetto.

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 } }

Esempi di errori reali dovuti alla mancanza di conoscenze sui dettagli dell'argomento.


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.