Classi locali e anonime
Dichiari classi all'interno dei metodi e crei al volo implementazioni anonime di interfacce.
Classi locali e anonime è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.
Classi locali e anonime
Le classi locali sono definite all'interno di un metodo. Le classi anonime sono classi locali senza nome: combinano la dichiarazione della classe e la sua istanziazione. Entrambe catturano le variabili locali effettivamente finali.
Dichiarazione di una classe locale
Una classe locale viene dichiarata all'interno del corpo di un metodo. Può accedere ai membri della classe che la contiene e alle variabili locali effettivamente finali.
static void greet(String language) {
// Local class — defined inside the method
class Greeter {
String sayHello(String name) {
// Can access 'language' — it is effectively final
return switch (language) {
case "EN" -> "Hello, " + name;
case "ES" -> "Hola, " + name;
case "FR" -> "Bonjour, " + name;
default -> "Hi, " + name;
};
}
}
Greeter g = new Greeter();
System.out.println(g.sayHello("Alice"));
}
greet("ES"); // Hola, AliceVariabili effettivamente finali
Le classi locali e anonime possono catturare solo variabili locali effettivamente finali, cioè variabili a cui non viene mai riassegnato un valore dopo l'inizializzazione.
void process(int threshold) {
// threshold is effectively final (never reassigned)
Runnable r = new Runnable() {
public void run() {
System.out.println("Threshold: " + threshold);
}
};
r.run();
// threshold = 10; // If you add this, the anonymous class won't compile
}Nozioni di base sulle classi anonime
Una classe anonima implementa un'interfaccia o estende una classe direttamente, all'interno di una singola espressione.
interface Comparator<T> {
int compare(T a, T b);
}
// Anonymous class implementing Comparator
java.util.Comparator<String> byLength = new java.util.Comparator<String>() {
@Override
public int compare(String a, String b) {
return Integer.compare(a.length(), b.length());
}
};
List<String> words = new ArrayList<>(List.of("banana", "fig", "apple", "kiwi"));
words.sort(byLength);
System.out.println(words); // [fig, kiwi, apple, banana]Classi anonime e lambda
Per le interfacce a singolo metodo astratto (SAM), le lambda sostituiscono le classi anonime. Le classi anonime sono comunque necessarie per le interfacce con più metodi o quando si estendono classi astratte.
// Anonymous class for single-method interface
Runnable r1 = new Runnable() {
public void run() { System.out.println("Running!"); }
};
// Lambda — cleaner for SAM interfaces
Runnable r2 = () -> System.out.println("Running!");
// Must use anonymous class for multi-method interface:
java.io.FilenameFilter filter = new java.io.FilenameFilter() {
public boolean accept(java.io.File dir, String name) {
return name.endsWith(".java");
}
}; // FilenameFilter is not a SAM — no lambda shorthandClasse anonima con stato
Le classi anonime possono avere campi, a differenza delle lambda. Sono utili quando è necessario mantenere uno stato all'interno dell'implementazione anonima.
interface Counter { int increment(); int get(); }
Counter counter = new Counter() {
private int count = 0;
public int increment() { return ++count; }
public int get() { return count; }
};
System.out.println(counter.increment()); // 1
System.out.println(counter.increment()); // 2
System.out.println(counter.get()); // 2Pattern dei listener anonimi
Prima delle lambda, le classi anonime erano il pattern standard per i listener di eventi nella programmazione GUI e Android.
// Modern Android/Swing style: anonymous class listener
Button loginButton = new Button(); // hypothetical
loginButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick() {
System.out.println("Login button clicked!");
}
});
// Modern equivalent with lambda (if OnClickListener is SAM):
loginButton.setOnClickListener(() -> System.out.println("Clicked!"));Classe locale per una logica complessa
Le classi locali sono adatte quando è necessaria una classe con più metodi in un unico punto: una situazione troppo complessa per una lambda, ma troppo specifica per una classe di primo livello.
static List<String> processData(List<String> data, String prefix) {
// Local class: complex enough for a class, used only here
class DataProcessor {
List<String> result = new ArrayList<>();
void process(String item) {
// prefix is effectively final
if (item.startsWith(prefix)) {
result.add(item.toUpperCase());
}
}
}
DataProcessor dp = new DataProcessor();
data.forEach(dp::process);
return dp.result;
}
System.out.println(processData(List.of("apple","avocado","banana"), "a"));
// [APPLE, AVOCADO]Classe anonima per una classe astratta
Le classi anonime possono estendere classi astratte, eseguendo l'override dei metodi astratti senza creare una sottoclasse con nome.
abstract class ReportFormatter {
abstract String formatHeader(String title);
abstract String formatBody(List<String> rows);
String format(String title, List<String> rows) {
return formatHeader(title) + "\n" + formatBody(rows);
}
}
ReportFormatter csvFormatter = new ReportFormatter() {
public String formatHeader(String t) { return "\"" + t + "\""; }
public String formatBody(List<String> rows) {
return String.join("\n", rows);
}
};
System.out.println(csvFormatter.format("Sales", List.of("a,1","b,2")));Anti-pattern dell'inizializzazione a doppia graffa
Il trucco dell'inizializzazione a doppia graffa utilizza classi anonime per inizializzare le raccolte. Crea una sottoclasse con un inizializzatore di istanza. È opportuno evitarlo: è inefficiente e soggetto a errori.
// Anti-pattern: double-brace initialization
Map<String, Integer> map = new HashMap<String, Integer>() {{
put("a", 1);
put("b", 2);
}};
// Creates an anonymous HashMap subclass — wasteful!
// GOOD: use Map.of() or Map.ofEntries()
Map<String, Integer> better = Map.of("a", 1, "b", 2);
// Or a mutable map:
Map<String, Integer> mutable = new HashMap<>(Map.of("a", 1, "b", 2));Scelta: lambda, classe anonima o classe locale
Guida alla scelta:
- Lambda: un singolo metodo astratto, nessuno stato aggiuntivo, nessuna ereditarietà
- Classe anonima: più metodi, necessità di mantenere uno stato o estensione di una classe astratta
- Classe locale: necessità di riutilizzo all'interno del metodo, più metodi, stato complesso
Verifica rapida
Che cosa fa sempre una classe anonima in una singola espressione?
Riepilogo: classi locali e anonime
Punti chiave:
- Le classi locali sono definite all'interno dei metodi e possono accedere alle variabili locali effettivamente finali
- Le classi anonime combinano la dichiarazione della classe e la sua istanziazione in una singola espressione
- Le classi anonime possono avere campi e più metodi, a differenza delle lambda
- Le lambda sostituiscono le classi anonime per le interfacce a singolo metodo astratto
- Utilizzare le classi locali quando la logica è abbastanza complessa da richiedere una classe, ma specifica per un solo metodo
- Evitare l'inizializzazione a doppia graffa: crea sottoclassi anonime non necessarie
Domande Frequenti
La lezione «Classi locali e anonime» è gratuita?
Sì — il testo completo di «Classi locali e anonime» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.
Cosa imparerò in «Classi locali e anonime»?
Dichiari classi all'interno dei metodi e crei al volo implementazioni anonime di interfacce. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Java Academy?
Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Classi locali e anonime»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Java Academy?
Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Classi annidate statiche
- Classi interne e accesso alla classe esterna
- Classi locali e anonime
- Scegliere la strategia di annidamento più adatta