Overview
Eine Methodenreferenz in Java ist eine Verkürzung, um einen Lambda-Ausdruck zu ersetzen.
Je größer Softwaresysteme werden, desto wichtiger wird ein kompakter und übersichtlicher Code. Die Einführung der Lambda-Syntax war für die Verbesserung der Code-Qualität ein Meilenstein.
In diesem Tutorial betrachten wir mit den Methoden-Referenzen die nächste Stufe dieser Entwicklung und wie wir damit den Code sogar noch kompakter schreiben können.
Anstelle von etwa folgendem Lambda-Ausdruck:
p -> System.out.println(p)
kann auch die passende Methoden-Referenz eingesetzt werden:
System.out::println
Eine Methoden-Referenz ist wie ein Lambda-Ausdruck ein Exemplar einer funktionalen Schnittstelle.
Wie du siehst, haben wir den Lambda-Ausdruck oben durch eine Methoden-Referenz ersetzt. Methoden-Referenzen haben folgende Syntax:
Klassennamen::Methodenname
Im Beispiel oben ist der Klassenname System.out und die Methode println.
Die Methode kann sowohl statisch (=statische Methodenreferenz) als auch eine Instanzmethode sein (=Instanz-Methodenreferenz).
Ein Lambda-Ausdruck macht eigentlich nichts anderes, als ein oder mehrere Argumente aufzunehmen und diese dann in eine Methode zu geben.
Dieser Mechanismus kann eben durch das Prinzip der Methoden-Referenz syntaktisch komprimiert werden: Wir können die Parameter auch gleich ganz weglassen. Durch den :: Operator werden die Parameter-Informationen durch den Compiler nämlich automatisch ermittelt und beim jeweiligen Methodenaufruf eingesetzt.
Schauen wir uns nun ein konkretes Beispiel für den Einsatz einer Methoden-Referenz an:
List<String> liste = Arrays.asList("The", "last", "of", "us");
liste.forEach(p -> System.out.println(p)); // Lambda
liste.forEach(System.out::println); // Methoden-Referenz
In diesem Beispiel haben wir die Implementierung des funktionalen Interfaces Consumer<T>, das von der forEach-Methode erwartet wird, auf zwei verschiedenen Wegen gelöst: Einmal mit einem Lambda-Ausdruck und einmal mit einer Methodenreferenz. Wie du siehst, können wir uns die Parameter in diesem Fall ganz sparen und zu einer wohl maximal kurzen Schreibweise übergeben.
Auch beim Sortieren von Listen durch die Implementierung des funktionalen Interfaces Comparator<T> lässt sich sinnvoll zu einer Methoden-Referenz übergeben. Zunächst sehen wir uns das Ganze noch mit einem Lambda-Ausdruck an:
List<Player> spieler = new ArrayList<>();
Player player1 = new Player(50);
Player player2 = new Player(40);
Player player3 = new Player(20);
spieler.add(player1);
spieler.add(player2);
spieler.add(player3);
// Lambda:
Collections.sort(spieler, (p1, p2) -> Integer.compare(p1.getPunkte(), p2.getPunkte()));
Den Ersatz der Lambda-Funktion durch eine alternative Methoden-Referenz lässt sich u.a. so lösen:
// Methoden-Referenz Variante 1:
Collections.sort(spieler, Comparator.comparingInt(Player::getPunkte));
Die statische Methode Comparator.comparingInt ist praktisch, da sie alles bietet was wir brauchen: Sie kann direkt eine Methoden-Referenz aufnehmen und liefert den für sort benötigten Comparator zurück.
Eine weitere Möglichkeit zum Einsatz einer Methoden-Referenz bei der Implementierung von Comparator sieht so aus:
// Methoden-Referenz Variante 2:
Collections.sort(spieler, Player::comparePunkte);
Diese Lösung setzt eine eine ausformulierte statische Methode in der Klasse Player voraus:
public static int comparePunkte(Player p1, Player p2){
return p1.getPunkte() - p2.getPunkte();
}
Java Basics
[Java einrichten] [Variablen] [Primitive Datentypen] [Operatoren] [if else] [switch-case] [Arrays] [Schleifen]
Objektorientierung
[Einstieg] [Variablen ] [Konstruktor] [Methoden] [Rekursion] [Statische Member] [Initializer] [Pass-by-value] [Objektsammlungen] [Objektinteraktion] [Objekte löschen]
Klassenbibliothek
[Allgemeines] [String ] [Math] [Wrapper] [Scanner] [java.util.Arrays] [Date-Time-API]
Vererbung
[Einstieg Vererbung] [Konstruktoren bei Vererbung ] [Der protected Zugriffsmodifikator] [Abstrakte Klassen und Methoden] [Polymorphie in Java] [Typumwandlung] [Die Klasse Object] [Die toString()-Methode] [Objekte vergleichen] [Was ist ein Interface?]