Paikalliset ja anonyymit luokat
Määritä luokkia metodien sisällä ja luo rajapintojen anonyymeja toteutuksia tarpeen mukaan.
Paikalliset ja anonyymit luokat on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.
Paikalliset ja anonyymit luokat
Paikalliset luokat määritellään metodin sisällä. Anonyymit luokat ovat nimettömiä paikallisia luokkia — ne yhdistävät luokan määrittelyn ja ilmentämisen. Molemmat voivat kaapata käytännössä final olevia paikallisia muuttujia.
Paikallisen luokan määrittely
Paikallinen luokka määritellään metodin rungon sisällä. Se voi käyttää ympäröivän luokan jäseniä ja käytännössä final olevia paikallisia muuttujia.
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, AliceKäytännössä final olevat muuttujat
Paikalliset ja anonyymit luokat voivat kaapata vain käytännössä final olevia paikallisia muuttujia — niitä ei määrittämisen jälkeen koskaan sijoiteta uudelleen.
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
}Anonyymien luokkien perusteet
Anonyymi luokka toteuttaa rajapinnan tai perii luokan suoraan yhdessä lausekkeessa.
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]Anonyymi luokka ja lambda
Yhden abstraktin metodin (SAM) rajapinnoissa lambdat korvaavat anonyymit luokat. Anonyymeja luokkia tarvitaan edelleen useita metodeja sisältäville rajapinnoille tai abstrakteja luokkia laajennettaessa.
// 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 shorthandTilaa sisältävä anonyymi luokka
Anonyymeilla luokilla voi olla kenttiä, toisin kuin lambdoilla. Tästä on hyötyä, kun anonyymin toteutuksen sisällä on säilytettävä tilaa.
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()); // 2Anonyymin kuuntelijan malli
Ennen lambdoja anonyymit luokat olivat graafisten käyttöliittymien ja Android-ohjelmoinnin vakiomalli tapahtumankuuntelijoille.
// 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!"));Paikallinen luokka monimutkaista logiikkaa varten
Paikalliset luokat sopivat tilanteisiin, joissa tarvitsette useita metodeja sisältävän luokan vain yhdessä paikassa — logiikka on lambdalle liian monimutkaista mutta ylätason luokalle liian erityistä.
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]Anonyymi luokka abstraktille luokalle
Anonyymit luokat voivat laajentaa abstrakteja luokkia ja ylikirjoittaa abstraktit metodit ilman nimettyä aliluokkaa.
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")));Kaksoisaaltosulkeiden alustuksen vastainen malli
Kaksoisaaltosulkeiden alustustemppu käyttää anonyymeja luokkia kokoelmien alustamiseen. Se luo aliluokan, jossa on instanssin alustuslohko. Välttäkää sitä — se on tehoton ja altis virheille.
// 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));Valinta: lambda, anonyymi vai paikallinen luokka
Ohje valintaan:
- Lambda: yksi abstrakti metodi, ei ylimääräistä tilaa eikä perintää
- Anonyymi luokka: useita metodeja, tarve tilalle tai abstraktin luokan laajentaminen
- Paikallinen luokka: uudelleenkäyttö metodin sisällä, useita metodeja tai monimutkainen tila
Pikatarkistus
Mitä anonyymi luokka tekee aina yhdessä lausekkeessa?
Kertaus: paikalliset ja anonyymit luokat
Tärkeimmät opit:
- Paikalliset luokat määritellään metodien sisällä, ja ne voivat käyttää käytännössä final olevia paikallisia muuttujia
- Anonyymit luokat yhdistävät luokan määrittelyn ja ilmentämisen yhteen lausekkeeseen
- Anonyymeilla luokilla voi olla kenttiä ja useita metodeja — toisin kuin lambdoilla
- Lambdat korvaavat anonyymit luokat yhden abstraktin metodin rajapinnoissa
- Käyttäkää paikallisia luokkia, kun logiikka on luokalle riittävän monimutkaista mutta koskee vain yhtä metodia
- Välttäkää kaksoisaaltosulkeiden alustusta — se luo tarpeettomia anonyymeja aliluokkia
Opi Java tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 104
- Oppitunnit
- 374
Usein kysytyt kysymykset
Onko oppitunti ”Paikalliset ja anonyymit luokat” ilmainen?
Kyllä – oppitunnin ”Paikalliset ja anonyymit luokat” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Paikalliset ja anonyymit luokat”?
Määritä luokkia metodien sisällä ja luo rajapintojen anonyymeja toteutuksia tarpeen mukaan. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.
Kuinka kauan ”Paikalliset ja anonyymit luokat”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?
Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Staattiset sisäkkäiset luokat
- Sisäluokat ja ympäröivän luokan käyttö
- Paikalliset ja anonyymit luokat
- Sopivan sisäkkäisyysstrategian valitseminen