Brugerdefinerede funktionelle interfaces
Definér Deres eget med @FunctionalInterface
Brugerdefinerede funktionelle interfaces er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Java Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Java Academy-kurset indeholder 4 lektioner i alt.
Hvad gør en grænseflade funktionel
En funktionel grænseflade har præcis én abstrakt metode (SAM). Det er denne ene metode, som en lambda implementerer.
- Default- og statiske metoder tæller ikke med i grænsen.
interface Greeter {
String greet(String name);
}
public class Main {
public static void main(String[] args) {
Greeter g = name -> "Hello, " + name;
System.out.println(g.greet("Ada"));
}
}Annoteringen @FunctionalInterface
@FunctionalInterface fortæller compileren, at den skal håndhæve reglen om én abstrakt metode. Hvis du ved et uheld tilføjer endnu en abstrakt metode, mislykkes kompileringen.
@FunctionalInterface
interface Calculator {
int compute(int a, int b);
}
public class Main {
public static void main(String[] args) {
Calculator add = (a, b) -> a + b;
System.out.println(add.compute(3, 4));
}
}Derfor er annoteringen nyttig
Annoteringen dokumenterer hensigten og beskytter kontrakten. Uden den fungerer grænsefladen stadig som en funktionel grænseflade, men en kollega kan ødelægge den ved at tilføje endnu en abstrakt metode.
@FunctionalInterface
interface Transformer {
String apply(String input);
}
public class Main {
public static void main(String[] args) {
Transformer reverse = s -> new StringBuilder(s).reverse().toString();
System.out.println(reverse.apply("abc"));
}
}Brugerdefineret grænseflade med generiske typer
Din grænseflade kan være generisk, ligesom de indbyggede grænseflader.
@FunctionalInterface
interface Converter<S, T> {
T convert(S source);
}
public class Main {
public static void main(String[] args) {
Converter<String, Integer> toInt = Integer::parseInt;
System.out.println(toInt.convert("123") + 1);
}
}Default-metoder er tilladt
En funktionel grænseflade må have default-metoder. De tilføjer funktionalitet uden at bryde reglen om én abstrakt metode.
@FunctionalInterface
interface Operation {
int apply(int x);
default Operation then(Operation next) {
return x -> next.apply(this.apply(x));
}
}
public class Main {
public static void main(String[] args) {
Operation inc = x -> x + 1;
Operation dbl = x -> x * 2;
System.out.println(inc.then(dbl).apply(5));
}
}Statiske metoder er også tilladt
Statiske metoder kan fungere som fabriksmetoder på samme måde som Function.identity().
@FunctionalInterface
interface Mapper {
int map(int x);
static Mapper identity() {
return x -> x;
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Mapper.identity().map(99));
}
}Udløsning af kontrollerede undtagelser
Hvis din abstrakte metode angiver en kontrolleret undtagelse, må lambdaen udløse den. Den indbyggede Function kan ikke gøre dette, hvilket er en af grundene til at definere din egen.
@FunctionalInterface
interface RiskyParser {
int parse(String s) throws NumberFormatException;
}
public class Main {
public static void main(String[] args) {
RiskyParser p = Integer::parseInt;
System.out.println(p.parse("77"));
}
}Overførsel af brugerdefinerede grænseflader til metoder
Din grænseflade bliver en parametertype, så kaldere kan levere adfærd via lambdaer.
@FunctionalInterface
interface IntCombiner {
int combine(int a, int b);
}
public class Main {
static int reduce(int[] arr, IntCombiner c) {
int acc = arr[0];
for (int i = 1; i < arr.length; i++) acc = c.combine(acc, arr[i]);
return acc;
}
public static void main(String[] args) {
int[] data = {1, 2, 3, 4};
System.out.println(reduce(data, (a, b) -> a + b));
}
}Grænseflade med tre argumenter
JDK indeholder kun grænseflader med ét eller to argumenter. Hvis du har brug for tre eller flere argumenter, skal du definere din egen.
@FunctionalInterface
interface TriFunction<A, B, C, R> {
R apply(A a, B b, C c);
}
public class Main {
public static void main(String[] args) {
TriFunction<Integer, Integer, Integer, Integer> sum3 = (a, b, c) -> a + b + c;
System.out.println(sum3.apply(1, 2, 3));
}
}Metodereferencer passer til brugerdefinerede grænseflader
Enhver metode, hvis signatur matcher SAM, kan leveres som en metodereference.
@FunctionalInterface
interface StringTest {
boolean check(String s);
}
public class Main {
public static void main(String[] args) {
StringTest blank = String::isBlank;
System.out.println(blank.check(" "));
}
}Anonym klasse kontra lambda
En lambda er en kortfattet erstatning for en anonym klasse, der implementerer en funktionel grænseflade. Begge dele giver den samme adfærd.
@FunctionalInterface
interface Action {
void run();
}
public class Main {
public static void main(String[] args) {
Action old = new Action() {
public void run() { System.out.println("anonymous"); }
};
Action neo = () -> System.out.println("lambda");
old.run();
neo.run();
}
}Hurtigt tjek
Hvad garanterer @FunctionalInterface?
Opsamling
Du definerede dine egne funktionelle grænseflader:
- En funktionel grænseflade har præcis én abstrakt metode (SAM).
@FunctionalInterfacehåndhæver reglen ved kompilering.- Default- og statiske metoder, generiske typer og kontrollerede undtagelser er alle tilladt.
- Brugerdefinerede grænseflader udfylder huller, som JDK ikke dækker, f.eks. funktioner med tre argumenter eller lambdaer med kontrollerede undtagelser.
Lær Java med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 104
- Lektioner
- 374
Ofte stillede spørgsmål
Er lektionen “Brugerdefinerede funktionelle interfaces” gratis?
Ja — hele teksten til “Brugerdefinerede funktionelle interfaces” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Java Academy-kurset, skal du opgradere til CoddyKit PRO. Java Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Brugerdefinerede funktionelle interfaces”?
Definér Deres eget med @FunctionalInterface Du øver dig i Java Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Java Academy?
Der kræves ingen tidligere erfaring. Java Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.
Hvor lang tid tager lektionen “Brugerdefinerede funktionelle interfaces”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Java Academy-lektion?
Ja. Alle Java Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Function og BiFunction
- Supplier og Consumer
- Predicate og komposition
- Brugerdefinerede funktionelle interfaces