Detaillierte Erläuterung der @FunctionalInterface-Annotation in Java

Kürzlich habe ich bei einer Teamcodeüberprüfung festgestellt, dass jemand die Annotation @FunctionalInterface verwendet hat. Ich bin mit dieser Anmerkung nicht sehr vertraut und habe sie im Grunde nie verwendet. Deshalb habe ich den entsprechenden Entwickler gebeten, mir zu erklären, wie ich diese Annotation verwenden soll. Warum sollte ich diese Annotation verwenden? Was er sagte, war nicht vollständig, also habe ich einige Informationen nachgeschlagen und sie mit allen geteilt!

Bevor wir über @FunctionalInterface sprechen, machen wir uns zunächst damit vertraut, was eine funktionale Schnittstelle (Functional Interface) ist.

1. Funktionsschnittstelle

Functional Interface ist der Name von Java 8 für einen speziellen Schnittstellentyp. Dieser Schnittstellentyp definiert nur die einzige Schnittstelle für abstrakte Methoden (mit Ausnahme der impliziten öffentlichen Methoden des Objektobjekts), sodass es sich zunächst um eine Schnittstelle vom Typ SAM (Single Abstract Method) handelt.

Um es ganz klar auszudrücken: Die sogenannte funktionale Schnittstelle ist natürlich zunächst eine Schnittstelle und dann eine abstrakte Methode, die nur eine öffentliche Methode eines Nicht-Objektobjekts in dieser Schnittstelle haben kann und mehrere statische Methoden und Standardmethoden haben kann Methoden.

Das Obige ist ein Konzept. Wenn Sie es noch nicht verstehen, spielt es keine Rolle. Fahren wir mit den folgenden Beispielen fort und ich glaube, Sie werden es verstehen.

Funktionsschnittstellen, die vor JDK 8 existierten.
Funktionsschnittstellen, die funktionale Programmierung unterstützten, wurden in JDKs bereitgestellt, die vor JDK 8 existierten.

java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
Java8 中新定义的函数式接口

In Java8 gibt es ein java.util.function-Paket. Es definiert funktionale Schnittstellen für mehrere Typengruppen und Unterschnittstellen für grundlegende Datentypen.

Predicate:传入一个参数,返回一个bool结果, 方法为boolean test(T t)
Consumer:传入一个参数,无返回值,纯消费。 方法为void accept(T t)
Function:传入一个参数,返回一个结果,方法为R apply(T t)
Supplier:无参数传入,返回一个结果,方法为T get()
UnaryOperator:一元操作符, 继承Function,传入参数的类型和返回类型相同。
BinaryOperator:二元操作符, 传入的两个参数的类型和返回类型相同, 继承 BiFunction

Schauen wir uns unten einen Fall an.

@FunctionalInterface
public interface XttblogService {
    void sayMessage(String message);
}

Dann können wir nun Lambda-Ausdrücke verwenden, um eine Implementierung dieser Schnittstelle darzustellen (Hinweis: Vor JAVA 8 wurde sie im Allgemeinen mit anonymen Klassen implementiert):

XttblogService xttblogService = message -> System.out.println("Hello " + message);

2. @FunctionalInterface-Annotation

2.1. Es kann nur einen öffentlichen Modifikator geben.

Wenn zwei definiert sind, wird ein Fehler gemeldet.

Wir können jedoch mehrere Standardmethoden definieren. Da die Standardmethode keine abstrakte Methode ist und über eine Standardimplementierung verfügt, entspricht sie der Definition einer funktionalen Schnittstelle.

@FunctionalInterface
public interface XttblogService{
    void sayMessage(String message);
    default void doSomeMoreWork1(){
        // 业余草:www.xttblog.com
    }
    default void doSomeMoreWork2(){
    }
}

2.2. Es können mehrere Standardmethoden definiert werden

Da die Standardmethode keine abstrakte Methode ist und über eine Standardimplementierung verfügt, entspricht sie der Definition einer funktionalen Schnittstelle.

@FunctionalInterface
public interface XttblogService{
    void sayMessage(String message);
    default void doSomeMoreWork1(){
        // 业余草:www.xttblog.com
    }
    default void doSomeMoreWork2(){
    }
}

2.3. Sie können auch mehrere statische Methoden definieren

@FunctionalInterface
public interface XttblogService {
    void sayMessage(String message);
    static void printHello(){
        System.out.println("Hello");
    }
    static void xttblogHello(){
        System.out.println("Xttblog Hello");
    }
}

Funktionale Schnittstellen ermöglichen die Definition von Standardmethoden und statischen Methoden, und keine der beiden oben genannten Methoden meldet einen Fehler.

2.4. Funktionale Schnittstellen ermöglichen auch die Definition öffentlicher Methoden in java.lang.Object.

Funktionale Schnittstellen können öffentliche Methoden in Object enthalten. Diese Methoden gelten nicht als abstrakte Methoden für funktionale Schnittstellen (obwohl es sich um abstrakte Methoden handelt), da jede Implementierung einer funktionalen Schnittstelle standardmäßig Object erbt. Klassen, die Implementierungen dieser abstrakten Methoden aus Java enthalten. lang.Objekt.

@FunctionalInterface
public interface XttblogService  {
    void sayMessage(String message);

    @Override
    boolean equals(Object obj);

    @Override
    String toString();

    @Override
    int hashCode();
}

Einige unserer häufig verwendeten Schnittstellen wie Callable, Runnable, Comparator usw. haben in JDK8 @FunctionalInterface-Annotationen hinzugefügt.

3. Warum wird die Annotation @FunctionalInterface in Java benötigt?

Ohne diese Annotation können wir auch Lambda-Ausdrücke implementieren.

Der Grund, warum Java die Annotation @FunctionalInterface eingeführt hat, liegt jedoch darin, dass das Entwicklungsteam bei der Implementierung von Java Lambda keinen speziellen Strukturfunktionstyp für Lambda-Ausdrücke, den sogenannten Pfeiltyp, mehr definieren und weiterhin das vorhandene Typsystem von Java verwenden möchte (Klasse, Schnittstelle, Methode usw.). Das Hinzufügen eines strukturierten Funktionstyps erhöht die Komplexität des Funktionstyps, zerstört vorhandene Java-Typen und hat schwerwiegende Folgen für Tausende von Java-Klassenbibliotheken. Wägen Sie die Vor- und Nachteile ab, sodass wir letztendlich die SAM-Schnittstelle als Zieltyp des Lambda-Ausdrucks verwenden.

Einige vorhandene Schnittstellen im JDK sind selbst funktionale Schnittstellen, wie beispielsweise Runnable. Das Paket java.util.function wurde zu JDK 8 hinzugefügt und bietet häufig verwendete Funktionsschnittstellen.

Eine funktionale Schnittstelle stellt einen Vertrag dar, einen Vertrag für einen bestimmten Funktionstyp. Wo es erscheint, wird tatsächlich eine vertragskonforme Funktion erwartet. Ein Lambda-Ausdruck kann nicht ohne Kontext existieren. Er muss einen klaren Zieltyp haben, und dieser Zieltyp ist eine funktionale Schnittstelle.

Ursprünglicher Link:  (Übertragung) Detaillierte Erläuterung des Verwendungs-Tutorials von @FunctionalInterface annotation_Leemeeas Blog-CSDN blog_FunctionalInterface-Annotation

おすすめ

転載: blog.csdn.net/m0_50370837/article/details/126212045