Neue Funktionen in Java 8

Neue Funktionen in Java 8

1. Überblick

In diesem Artikel werden einige der interessantesten neuen Funktionen in Java 8 kurz vorgestellt.

Wir werden über Folgendes sprechen: Standard- und statische Schnittstellenmethoden, Methodenreferenz und Optional.

Wir haben bereits einige Funktionen der Java 8-Version behandelt -stream API,lambda expressions and functional interfaces -, da es sich um umfassende Themen handelt, die einen gesonderten Blick verdienen.

2. Standard- und statische Schnittstellenmethoden

Vor Java 8 konnten Interfaces nur öffentliche abstrakte Methoden haben. Es war weder möglich, der vorhandenen Schnittstelle neue Funktionen hinzuzufügen, ohne alle implementierenden Klassen zu zwingen, eine Implementierung der neuen Methoden zu erstellen, noch war es möglich, Schnittstellenmethoden mit einer Implementierung zu erstellen.

Ab Java 8 können Schnittstellen Methodenstatic unddefaulthaben, die, obwohl sie in einer Schnittstelle deklariert sind, ein definiertes Verhalten aufweisen.

2.1. Statische Methode

Betrachten Sie die folgende Methode der Schnittstelle (nennen wir diese SchnittstelleVehicle):

static String producer() {
    return "N&F Vehicles";
}

Die statischeproducer()-Methode ist nur über und innerhalb einer Schnittstelle verfügbar. Es kann nicht von einer implementierenden Klasse überschrieben werden.

Um es außerhalb der Schnittstelle aufzurufen, sollte der Standardansatz für den statischen Methodenaufruf verwendet werden:

String producer = Vehicle.producer();

2.2. Standardmethode

Standardmethoden werden mit den neuendefault keyword deklariert. Diese sind über die Instanz der implementierenden Klasse zugänglich und können überschrieben werden.

Fügen wir unsererVehicle-Schnittstelle einedefault-S-Methode hinzu, die auch diestatic-S-Methode dieser Schnittstelle aufruft:

default String getOverview() {
    return "ATV made by " + producer();
}

Angenommen, diese Schnittstelle wird von der KlasseVehicleImpl.implementiert. Zum Ausführen der Methodedefault sollte eine Instanz dieser Klasse erstellt werden:

Vehicle vehicle = new VehicleImpl();
String overview = vehicle.getOverview();

3. Methodenreferenzen

Die Methodenreferenz kann als kürzere und besser lesbare Alternative für einen Lambda-Ausdruck verwendet werden, der nur eine vorhandene Methode aufruft. Es gibt vier Varianten von Methodenreferenzen.

3.1. Verweis auf eine statische Methode

Der Verweis auf eine statische Methode enthält die folgende Syntax:ContainingClass::methodName.

Versuchen wir, mithilfe der Stream-API alle leeren Zeichenfolgen inList<String>zu zählen.

boolean isReal = list.stream().anyMatch(u -> User.isRealUser(u));

Schauen Sie sich den Lambda-Ausdruck in deranyMatch()-Methode genauer an. Er ruft lediglich eine statische MethodeisRealUser(User user) derUser-Klasse auf. Es kann also durch einen Verweis auf eine statische Methode ersetzt werden:

boolean isReal = list.stream().anyMatch(User::isRealUser);

Diese Art von Code sieht viel informativer aus.

3.2. Verweis auf eine Instanzmethode

Der Verweis auf eine Instanzmethode enthält die folgende Syntax:containingInstance::methodName. Der folgende Code ruft die MethodeisLegalName(String string) vom TypUser auf, die einen Eingabeparameter validiert:

User user = new User();
boolean isLegalName = list.stream().anyMatch(user::isLegalName);

3.3. Verweis auf eine Instanzmethode eines Objekts eines bestimmten Typs

Diese Referenzmethode verwendet die folgende Syntax:ContainingType::methodName. Ein Beispiel
long count = list.stream().filter(String::isEmpty).count();

3.4. Verweis auf einen Konstruktor

Eine Referenz auf einen Konstruktor hat die folgende Syntax:ClassName::new. Da der Konstruktor in Java eine spezielle Methode ist, kann die Methodenreferenz auch mit Hilfe vonnew als Methodenname. auf ihn angewendet werden

Stream stream = list.stream().map(User::new);

4. Optional

Bevor Java 8-Entwickler die von ihnen genannten Werte sorgfältig validieren mussten, bestand die Möglichkeit, dieNullPointerException (NPE) zu werfen. All diese Überprüfungen erforderten einen ziemlich nervigen und fehleranfälligen Code.

Die Klasse Java 8Optional<T>kann helfen, Situationen zu behandeln, in denen die Möglichkeit besteht,NPE. abzurufen. Sie fungiert als Container für das Objekt vom TypT.. Sie kann einen Wert dieses Objekts zurückgeben, wenn Dieser Wert ist keinnull. Wenn der Wert in diesem Containernull ist, können einige vordefinierte Aktionen ausgeführt werden, anstattNPE. zu werfen

4.1. Erstellung derOptional<T>

Eine Instanz der KlasseOptionalkann mit Hilfe ihrer statischen Methoden erstellt werden:

Optional optional = Optional.empty();

Gibt ein leeresOptional. zurück

String str = "value";
Optional optional = Optional.of(str);

Gibt einOptional zurück, das einen Wert ungleich Null enthält.

Optional optional = Optional.ofNullable(getString());

Gibt einOptional mit einem bestimmten Wert oder ein leeresOptional zurück, wenn der Parameternull. ist

4.2. Optional<T> usage

Zum Beispiel erwarten Sie einList<String> und im Fall vonnull möchten Sie es durch eine neue Instanz einesArrayList<String>.With-Codes vor Java 8 ersetzen müssen so etwas tun:

List list = getList();
List listOpt = list != null ? list : new ArrayList<>();

Mit Java 8 kann die gleiche Funktionalität mit einem viel kürzeren Code erreicht werden:

List listOpt = getList().orElseGet(() -> new ArrayList<>());

Es gibt noch mehr Boilerplate-Code, wenn Sie das Feld eines Objekts auf die alte Weise erreichen müssen. Angenommen, Sie haben ein Objekt vom TypUser, das ein Feld vom TypAddress mit einem Feld streetvom TypString. hat. Aus irgendeinem Grund müssen Sie einen Wert von zurückgeben das Feldstreet, falls vorhanden, oder ein Standardwert, wennstreetnull ist:

User user = getUser();
if (user != null) {
    Address address = user.getAddress();
    if (address != null) {
        String street = address.getStreet();
        if (street != null) {
            return street;
        }
    }
}
return "not specified";

Dies kann mitOptional: vereinfacht werden

Optional user = Optional.ofNullable(getUser());
String result = user
  .map(User::getAddress)
  .map(Address::getStreet)
  .orElse("not specified");

In diesem Beispiel haben wir die Methodemap() verwendet, um die Ergebnisse des Aufrufs vongetAdress() inOptional<Address> undgetStreet() inOptional<String>. umzuwandeln. Wenn eine dieser Methodennull Die Methodemap() würde ein leeresOptional. zurückgeben

Stellen Sie sich vor, unsere Getter gebenOptional<T>. zurück. Daher sollten wir die MethodeflatMap() anstelle vonmap(): verwenden

Optional optionalUser = Optional.ofNullable(getOptionalUser());
String result = optionalUser
  .flatMap(OptionalUser::getAddress)
  .flatMap(OptionalAddress::getStreet)
  .orElse("not specified");

Ein anderer Anwendungsfall vonOptional ist das Ändern vonNPE mit einer anderen Ausnahme. Versuchen wir also, wie zuvor, dies im Stil vor Java 8 zu tun:

String value = null;
String result = "";
try {
    result = value.toUpperCase();
} catch (NullPointerException exception) {
    throw new CustomException();
}

Und was ist, wenn wirOptional<String> verwenden? Die Antwort ist lesbarer und einfacher:

String value = null;
Optional valueOpt = Optional.ofNullable(value);
String result = valueOpt.orElseThrow(CustomException::new).toUpperCase();

Beachten Sie, dass die Verwendung vonOptional in Ihrer App eine ernsthafte und kontroverse Entwurfsentscheidung ist und die Erläuterung aller Vor- und Nachteile nicht in den Geltungsbereich dieses Artikels fällt. Wenn Sie interessiert sind, können Sie tiefer graben, es gibt viele interessante Artikel im Internet, die sich mit diesem Problem befassen. This one undthis another one könnten sehr hilfreich sein.

5. Fazit

In diesem Artikel diskutieren wir kurz einige interessante neue Funktionen in Java 8.

Es gibt natürlich viele andere Ergänzungen und Verbesserungen, die über viele Java 8-JDK-Pakete und -Klassen verteilt sind.

Die Informationen in diesem Artikel sind jedoch ein guter Ausgangspunkt, um einige dieser neuen Funktionen kennenzulernen.

Schließlich ist der gesamte Quellcode für den Artikelover on GitHub. verfügbar