Wie funktioniert die Methodenreferenzsyntax in Java 8 [Duplikat]

Sep 28 2020

Ich habe einige Verwirrung darüber, wie Methodenreferenzen in Java 8 funktionieren. Ich habe das folgende Codesegment zum Filtern versteckter Dateien in einem Ordner geschrieben. Sie liefern das richtige Ergebnis. Ich verstehe nicht -> wie die Methodensignatur der listFiles-Methode für Option 2 dieses Codesegments funktioniert.

Dies habe ich in der Java 8-Dokumentation gefunden

  1. File[] listFiles()
  2. File[] listFiles(FileFilter filter)
  3. File[] listFiles(FilenameFilter filter)
File[] hidden = f.listFiles((p)-> p.isHidden()); //Option 1 - function signature matching (based on my understanding)
for (int i = 0; i < hidden.length; i++) {
    System.out.println(hidden[i]);
}
System.out.println("================================");
File[] hidden1 = f.listFiles(File::isHidden); //Option 2 - how this method call is working
for (int i = 0; i < hidden1.length; i++) {
    System.out.println(hidden1[i]);
}

Antworten

4 KeyMaker00 Sep 28 2020 at 13:08

Was ist eine Methodenreferenz?

Sie können eine Methodenreferenz als Lambda-Ausdruck sehen, der eine vorhandene Methode aufruft.

Arten von Methodenreferenzen

Es gibt vier Arten von Methodenreferenzen:

  • Verweis auf eine statische Methode: ContainingClass::staticMethodName
  • Verweis auf eine Instanzmethode eines bestimmten Objekts: containingObject::instanceMethodName
  • Verweis auf eine Instanzmethode eines beliebigen Objekts eines bestimmten Typs: ContainingType::methodName
  • Verweis auf einen Konstruktor: ClassName::new

Wie verstehe ich das?

Der folgende Ausdruck, der alle versteckten Dateien auflistet: f.listFiles(p -> p.isHidden());

Dieser Ausdruck besteht aus der Instanzmethode listFiles(FileFilter)und Ihrem Lambda-Ausdruck p -> p.isHidden(), der keine anonyme Methode, sondern eine vorhandene Instanzmethode der Klasse ist File.

Beachten Sie, dass dies FileFiltereine funktionale Schnittstelle ist und daher als Zuweisungsziel für einen Lambda-Ausdruck oder eine Methodenreferenz verwendet werden kann. Daher können Sie Ihren Ausdruck schreibenf.listFiles(File::isHidden);

Randnotizen

  1. Sie brauchen die Klammern um das nicht p. Für eine bessere Lesbarkeit würde ich vorschlagen, (p)einfach durch a zu ersetzen p. Daher wird Ihr Lambda-Ausdruck p-> p.isHidden().
  2. Ihre for-Schleife kann durch eine erweiterte for-Schleife ersetzt werden:
for (File value : hidden) {
   System.out.println(value);
}

Dokumentation:

Methodenreferenz

FileFilter