Erste Schritte Anfängerfrage zu ::new

pkm

Bekanntes Mitglied
Ich habe gesehen, dass man mit der Syntax von Lambdaausdrücken auch den Konstruktor mit dem ::-Operator aufrufen kann. Dass man auf eine Methode mit :: zugreifen kann, kenne ich nur aus der Iteration über Listen, z. B.

Code:
List<String> myList = new Arraylist<>();
  myList.add("eins");
  myList.add("zwei");

myList.forEach(System.out::println);

Aber in welchen Fällen wird sonst mit dem ::-Operator auf Methoden zugegriffen und vor allem, wann wird mit dem ::-Operator auf new zugegriffen :):new)?
 

httpdigest

Top Contributor
Ersteinmal ein bisschen zum Hintergrund von Lambda-Ausdrücken in Java:
Ein Lambda-Ausdruck ist nur "syntaktischer Zucker" für die automatische Implementierung eines Interfaces mit nur einer abstrakten (also nicht-default) Methode, wobei die tatsächliche Implementierung leichtgewichtiger ist als eine normale Klasse oder anonyme Klasse. Im Java-Umfeld nennt man solche Interfaces, die nur eine abstrakte Methode haben, neuerdings auch "functional Interfaces" und es gibt sogar eine Annotation, die reinen Dokumentationscharakter hat, um sowas auch zu dokumentieren: java.lang.FunctionalInterface.
Es hängt jetzt vom Anwendungskontext ab, wo genau Lambda-Ausdrücke erlaubt sind. Sie sind überall dort erlaubt, wo man sonst eine Instanz eines funktionalen Interfaces angeben müsste. Also z.B. wenn man einer Variablen von solch einem Interfacetyp einen Wert zuweisen möchte:
Java:
Supplier<String> s = () -> "Hello";
Supplier ist dabei das java.util.function.Supplier Interface, und es hat genau eine Methode mit der Signatur: `T get()`, also die Methode bekommt keinen Parameter, liefert aber ein T zurück. Was das T dann genau ist, liefert das Typargument bei der konkreten Instanziierung der Klasse, die das Interface implementiert.
Eine weitere Stelle, an der man Lambda-Ausdrücke anwenden kann (und das ist wohl die häufigste), ist als Argument für Methodenparameter vom Typ eines funktionalen Interfaces. Schaue dir z.B. einmal folgende Methodensignatur an:
Java:
<T> T give(Supplier<T> s)
Eine solche Methode _könnte_ nun den obigen Lambda-Ausdruck bekommen, und z.B. folgendes tun:
Java:
<T> T give(Supplier<T> s) {
  return s.get();
}
void main() {
  String str = give(() -> "Hello");
}
Sie kann also einen Supplier auswerten, und zum Zeitpunkt der Auswertung den Wert liefern, den der Supplier zu diesem Zeitpunkt liefert. Das ist interessant für "Lazy Evaluation", in der man Berechnungen erstmal als Lambda-Funktionen (sprich: Implementierungen eines funktionalen Interfaces) bereithalten möchte, um sie dann bei Bedarf auszuwerten.
Zugegeben, das sind alles ausgedachte Beispiele, aber ich finde es wichtig, dass man erstmal genau festhält, was ein Lambda-Ausdruck eigentlich genau ist.
Kommen wir jetzt zu Methodenreferenzen. Methodenreferenzen sind weiterer syntaktischer Zucker, um das funktionale Interface in solch einer Form zu implementieren, dass die Implementierung der abstrakten Methode einfach nur die Methode, dessen Referenz man angibt, aufruft.
Im obigen Beispiel könnte man also schreiben:
Java:
<T> T give(Supplier<T> s) {
  return s.get();
}
String sayHello() {
  return "Hello";
}
void main() {
  String str = give(this::sayHello);
}
Siehst du, was hier passiert? Die Methodenreferenz auf die Instanzmethode "sayHello" ist kompatibel zur Signatur der Methode "get" im Supplier, in der Form, als dass beide keinen Parameter bekommen und ein T zurückliefern. Das T ist in diesem Fall nun instanziiert mit String und schon haben wir einen kompatiblen Aufruf über das Supplier Interface auf unsere sayHello Methode.
Mehr sind Methodenreferenzen nicht. Nur ein syntaktisches Mittel, um eine Instanzmethode, statische Methode oder Konstruktor auf ein funktionales Interface zu "adaptieren".
Jetzt noch kurz zu Konstruktoren. Die Signatur einer Referenz eines Konstruktors hat immer als Rückgabetyp den Typ, der der Konstruktur instanziiert (bzw. initialisiert) und genau die Parameter, die auch der Konstruktor hat.
Ein "no-args" Konstruktor, der also keine Parameter bekommt, wäre immer kompatibel zum Supplier-Interface, da in beiden Fällen Methoden gemeint sind, die keine Parameter bekommen, und ein T zurückliefern.
Unser Beispiel weitergespinnt, könnte man z.B: sowas machen:
Java:
    <T, C extends Collection<T>> C transform(Collection<? extends T> coll, Supplier<C> f) {
        C ret = f.get();
        ret.addAll(coll);
        return ret;
    }
 
    void main(String[] args) {
        List<String> arrayList = new ArrayList<>();
        Set<String> set = transform(arrayList, HashSet::new);
    }
Das geht natürlich viel kürzer mit `set = new HashSet(arrayList)`, aber es soll erstmal nur aufzeigen, was Konstruktorreferenzen genau sind.
Jetzt aber zu der Frage: Wann wird das denn alles gebraucht? Lambda-Ausdrücke, Methodenreferenzen und Konstruktorreferenzen? Das alles sind zumindest mal Versuche, funktionale Programmierung in die eigentlich stark objektorientierte JVM-Welt zu bekommen. Ich persönlich benutze Lambdausdrücke und Methodenreferenzen eigentlich nie. Es gab bisher noch keine wirklichen Anwendungsfälle für mich.
Ein Grund dafür kann z.B. auch sein, dass Java noch keine starke Typinferenz unterstützt, wie etwa Haskell, und deswegen jede Benutzung und auch selbstentwickelte Methoden mit funktionalen Interface ein wahres Monster an Generics-Typendeklarationen werden.
Die JVM ist eben doch in ihrem Kern rein objektorientiert und hat Funktionen nicht als First-Class-Citizens, sodass funktionale Programmierung erst wirklich Sinn macht. Aber jetzt schweife ich ab. :)
 

mrBrown

Super-Moderator
Mitarbeiter
es gibt sogar eine Annotation, die reinen Dokumentationscharakter hat, um sowas auch zu dokumentieren: java.lang.FunctionalInterface.
Nicht nur Dokumentationscharakter, die Annotation auf nicht passendem Typen führt auch zu einem Compile-Fehler (analog zu z.B. @Override) ;)

Ich persönlich benutze Lambdausdrücke und Methodenreferenzen eigentlich nie. Es gab bisher noch keine wirklichen Anwendungsfälle für mich.
Ein Grund dafür kann z.B. auch sein, dass Java noch keine starke Typinferenz unterstützt, wie etwa Haskell, und deswegen jede Benutzung und auch selbstentwickelte Methoden mit funktionalen Interface ein wahres Monster an Generics-Typendeklarationen werden.
Ich benutze die ziemlich häufig, um mal etwas Gewicht auf die andere Seite der Waage zu legen ;)

Allerdings stoß ich eher selten an die Grenzen der Typinferenz, wo muss man denn da wahre Monster erschaffen?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Anfängerfrage zu meinem Programm. Java Basics - Anfänger-Themen 15
V Anfängerfrage: HelloWorld läuft nicht Java Basics - Anfänger-Themen 3
F if else if anfängerfrage Java Basics - Anfänger-Themen 22
P Anfängerfrage, Primitiv,komplex Java Basics - Anfänger-Themen 1
A Anfängerfrage Java Basics - Anfänger-Themen 7
M Erstellung Interfaces....totale Anfängerfrage Java Basics - Anfänger-Themen 16
W DNS Name auslesen + weitere Anfängerfrage Java Basics - Anfänger-Themen 4
R Anfängerfrage zu Methoden in Vererbte Klassen Java Basics - Anfänger-Themen 2
F Erste Schritte (Gelöst) Anfängerfrage Arraylist ausserhalb der Main Methode Java Basics - Anfänger-Themen 2
DeVolt Anfängerfrage zu util.scanner Java Basics - Anfänger-Themen 2
T Anfängerfrage zu Schleifen und Arrays Java Basics - Anfänger-Themen 5
B Collections ArrayList füllen - Anfängerfrage Java Basics - Anfänger-Themen 1
Shams Anfängerfrage zu jnlp Java Basics - Anfänger-Themen 0
T Kleine Anfängerfrage :) Java Basics - Anfänger-Themen 4
I Anfängerfrage JPanel repaint() Java Basics - Anfänger-Themen 6
F Anfängerfrage zu extends Java Basics - Anfänger-Themen 12
A Anfängerfrage: Zahlformat prüfen Java Basics - Anfänger-Themen 4
I Anfängerfrage: Fehlersuche Java Basics - Anfänger-Themen 2
A Methoden Anfängerfrage: 2 Listen Vergleichen Java Basics - Anfänger-Themen 7
L Anfängerfrage zu TileMap Java Basics - Anfänger-Themen 4
J anfängerfrage Java Basics - Anfänger-Themen 10
J Anfängerfrage HelloWorld? cmd-Problem Java Basics - Anfänger-Themen 35
J Anfängerfrage zu Grundlagen von Packages Java Basics - Anfänger-Themen 7
J Anfängerfrage zur Variablen Java Basics - Anfänger-Themen 11
J Anfängerfrage :-) Java Basics - Anfänger-Themen 5
M Banale Anfängerfrage Java Basics - Anfänger-Themen 3
Y Anfängerfrage zu array(-Syntax) Java Basics - Anfänger-Themen 6
J Leichte Java Anfängerfrage. Bitte schnelle Antwort. :) Java Basics - Anfänger-Themen 10
U Anfängerfrage - Multithreading Java Basics - Anfänger-Themen 8
T Aufrufen von get-Methode aus anderer Klasse (absolute Anfängerfrage) Java Basics - Anfänger-Themen 2
G Anfängerfrage zu "@Override" Java Basics - Anfänger-Themen 5
N Anfängerfrage richtige Syntax und Frage zu Vector Java Basics - Anfänger-Themen 7
A Anfängerfrage - array required, but java.lang.String found Java Basics - Anfänger-Themen 7
M Kleine Anfängerfrage Java Basics - Anfänger-Themen 10
S Anfängerfrage zu Array Java Basics - Anfänger-Themen 8
K Anfängerfrage: Fehlermeldung Java Basics - Anfänger-Themen 6
D Anfängerfrage N. Office Access NOA: setHidden und dann . Java Basics - Anfänger-Themen 2
N Anfängerfrage Java Basics - Anfänger-Themen 14
N anfängerfrage. returnwerte Java Basics - Anfänger-Themen 3
Gama Importieren von Klassen [Anfängerfrage] Java Basics - Anfänger-Themen 3
G Anfängerfrage Java Basics - Anfänger-Themen 11
B Anfängerfrage zu Swing "Reload" Java Basics - Anfänger-Themen 2
N Anfängerfrage bezüglich Speicherverwaltung Java Basics - Anfänger-Themen 3
G Anfängerfrage zu Threads Java Basics - Anfänger-Themen 14
Q Anfängerfrage Java Basics - Anfänger-Themen 6
J Anfängerfrage: wie externe Dateien importieren? Java Basics - Anfänger-Themen 5
S Anfängerfrage Java Basics - Anfänger-Themen 7
G Anfängerfrage zu Vererbung Java Basics - Anfänger-Themen 6
B Anfängerfrage zu 'NoClassDefFoundError' Java Basics - Anfänger-Themen 2
J IO Frage Hex-Output - Anfängerfrage Java Basics - Anfänger-Themen 5
T Anfängerfrage -> Projekt Java Basics - Anfänger-Themen 2
C Anfängerfrage ->Objekte und Arrays Java Basics - Anfänger-Themen 4
V Anfängerfrage Java Basics - Anfänger-Themen 8
E RMI Anfängerfrage Java Basics - Anfänger-Themen 10
DEvent anfängerfrage: wieso layout erst beim verändern? Java Basics - Anfänger-Themen 6
G Anfängerfrage Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben