Java 8 bietet einige neue Funktionen, auf welche ich in diesem Artikel eingehen möchte. Wenn euch etwas fehlt oder ihr einen Fehler finden solltet, könnt ihr mich gerne in den Kommentaren darauf hinweisen 😉
Lambda Expressions
Unter Java 7 benötigt die Übergabe eines Listeners zu einer Klasse ziemlich viel unnötigen Code. Ein typisches Beispiel bei Android ist das Hinzufügen eines OnClickListeners
zu einem Button
:
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { handleClick(); } });
Mit der Hilfe von Lambda Expressions kann das alles in einer Zeile zusammengefasst werden:
button.setOnClickListener(view --> handleClick());
Das ist schon mal ziemlich cool. Jetzt stellt sich natürlich die Frage, wie Lambda Expressions überhaupt funktionieren?
Lambda Expressions sind syntaktischer Zucker. So werden Syntaxerweiterungen genannt, welche der Vereinfachung von Schreibweisen dienen. Lambda Expressions erlauben das Erstellen von anonymen Methoden in einer kürzeren und besser lesbaren Syntax. Es wird verhindert, dass bei functional Interfaces anonyme Klassen explizit erzeugt werden müssen. Functional Interfaces sind Interfaces mit genau einer Methode. Ein Beispiel ist der OnClickListener
:
// ein functional Interface hat genau eine Methode public interface OnClickListener { void onClick(View view); }
Lambda Expressions bestehen grundsätzlich aus 3 Teilen:
button.setOnClickListener((view) -> {handleClick()});
- Der Deklaration der Parameter zwischen zwei Klammern
()
- Einem Pfeil, dem sogenannten Lambda-Operator
->
- Dem auszuführenden Code zwischen zwei geschweiften Klammern
{}
Wird nur ein Eingabeparameter verwendet, können sogar die Klammern ()
weggelassen werden:
button.setOnClickListener(view -> {handleClick()});
Das gleiche gilt für die beiden Klammern {}
beim auszuführenden Code, wenn dieser nur eine Anweisung enthält:
button.setOnClickListener(view -> handleClick())
Method References
Wie wir gerade gesehen haben, vereinfachen Lambda Expressions den Code bei funktionalen Interfaces. Method References gehen noch einen Schritt weiter. Wenn über die Lambda Expressions eine bereits vorhandene Methode aufgerufen wird, kann der Code mit Method References nochmals vereinfacht werden:
button.setOnClickListener(this::handleClick);
Dabei ist zu beachten, dass der referenzierten Methode genau die gleichen Parameter übergeben werden müssen wie dem funktionalen Interface. Beim Beispiel oben muss also noch der Parameter View view
hinzugefügt werden:
// functional interface public interface OnClickListener { void onClick(View view); } // referenzierte Methode: Muss das Argument View besitzen, da die onClick()-Methode es ebenfalls enthält private void handleClick(View view) { // do something here }
Method References sind also ebenfalls syntaktischer Zucker, mit welchem die folgende Referenzen vereinfacht werden können:
Statische Methoden | MyClass::doSomething |
Instanzmethoden eines Objekts | myObject::doSomething |
Konstruktor | MyClass::new |
Instanzmethoden | String::compare |
Mehr dazu unter https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html.
Default (Interface) Methods
Default Methods ermöglichen das Hinzufügen von Methoden zu einem Interface, ohne dabei alle Klassen “kaputt zu machen”, welche das Interface bereits implementieren. Stellen wir uns beispielsweise vor, dass wir ein Interface MyInterface
haben, welches von der Klasse MyClass
implementiert wird:
public interface MyInterface { void doIt(); } public class MyClass implements MyInterface { @Override public void doIt() { // mach etwas } }
Wenn wir nun eine zusätzliche Methode zum Interface MyInterface
hinzufügen wollen, kann der Code nicht mehr kompiliert werden. Erst nachdem wir die Methode auch zu MyClass
hinzugefügt haben, würde es wieder funktionieren. Das kann vor allem dann problematisch sein, wenn viele Klassen das Interface bereits implementieren.
Deswegen ist es ab Java 8 möglich sogenannte Default Methods hinzuzufügen, welche eine Standardimplementierung mitbringen:
public interface MyInterface { void doIt(); default void doThatToo() { // mach etwas } }
Wir können also einfach das Keyword default
zur Interfacemethode hinzufügen und so das Standardverhalten der Methode implementieren.
Tipps
Zu Beginn erscheinen die neuen Funktionen sicherlich etwas kompliziert bzw. ungewohnt. IntelliJ bietet jedoch eine automatische Umwandlung (quick fixes) an, welche das Erlernen der Java 8 Features deutlich vereinfacht. Mit der Tastenkombination alt/command
+ enter
können funktionale Interfaces zu Lambda Expressions und Lambda Expressions zu Method References umgewandelt werden. So kannst du den Code zu Beginn schreiben, wie du es ohnehin gewohnt bist. Nach genügend quick fixes von IntelliJ wirst du nach und nach lernen, wann du Lambda Expressions und Method References verwenden kannst.
Ich hoffe, ich konnte dir mit diesem Artikel etwas weiterhelfen. Über einen Kommentar würde ich mich sehr freuen 🙂
0 Kommentare